[med-svn] [seqan2] 01/01: New upstream version 2.3.2.000platform-issues0-8ae7bc0+dfsg1

Michael Crusoe misterc-guest at moszumanska.debian.org
Tue Oct 24 07:15:17 UTC 2017


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

misterc-guest pushed a commit to annotated tag upstream/2.3.2.000platform-issues0-8ae7bc0+dfsg1
in repository seqan2.

commit f945f1430a95303e2eadef02bfdad4e61e9b2ab2
Author: Michael R. Crusoe <michael.crusoe at gmail.com>
Date:   Mon Oct 23 09:27:28 2017 -0700

    New upstream version 2.3.2.000platform-issues0-8ae7bc0+dfsg1
---
 CMakeLists.txt                                     |    5 +-
 apps/mason2/mason_options.cpp                      |   38 +-
 apps/mason2/mason_options.h                        |    4 +
 apps/mason2/vcf_materialization.cpp                |    7 +-
 apps/micro_razers/micro_razers.cpp                 |    1 +
 apps/seqan_tcoffee/README                          |   22 +-
 apps/seqan_tcoffee/seqan_tcoffee.cpp               |   37 +-
 apps/sgip/sgip.cpp                                 |    2 +-
 apps/splazers/splazers.cpp                         |    1 +
 demos/tutorial/a_first_example/final_result.cpp    |   22 +-
 .../a_first_example/final_result.cpp.stdout        |   13 +-
 demos/tutorial/a_first_example/solution_1.cpp      |    4 -
 demos/tutorial/a_first_example/solution_2.cpp      |    6 +-
 .../tutorial/a_first_example/solution_2.cpp.stdout |    2 +-
 demos/tutorial/a_first_example/solution_3.cpp      |    6 +-
 .../tutorial/a_first_example/solution_3.cpp.stdout |    2 +-
 demos/tutorial/a_first_example/solution_4.cpp      |    4 +-
 .../tutorial/a_first_example/solution_4.cpp.stdout |    3 +-
 .../solution_4_templateSubclassing.cpp             |    2 -
 demos/tutorial/a_first_example/solution_5.cpp      |   10 +-
 .../tutorial/a_first_example/solution_5.cpp.stdout |    4 +-
 demos/tutorial/a_first_example/solution_6.cpp      |   20 +-
 .../tutorial/a_first_example/solution_6.cpp.stdout |   12 +-
 demos/tutorial/blast_io/write_assignment.cpp       |    3 +-
 demos/tutorial/iterators/assignment_1_solution.cpp |    4 +-
 demos/tutorial/sequences/base.cpp                  |    2 +-
 include/seqan/align.h                              |    1 +
 include/seqan/align/dp_algorithm_impl.h            |   19 +-
 include/seqan/align/dp_align_simd_helper.h         |  110 +-
 include/seqan/align/dp_meta_info.h                 |    2 +-
 include/seqan/align/dp_profile.h                   |   12 +
 include/seqan/align/dp_scout_simd.h                |  282 +++-
 include/seqan/align/dp_traceback_impl.h            |    8 +-
 include/seqan/arg_parse/arg_parse_version_check.h  |   16 +-
 include/seqan/bam_io/bam_alignment_record.h        |   49 +-
 include/seqan/bam_io/bam_index_bai.h               |    4 +-
 include/seqan/bam_io/bam_sam_conversion.h          |    2 +-
 include/seqan/bam_io/read_bam.h                    |    2 +-
 include/seqan/basic.h                              |    3 -
 include/seqan/basic/alphabet_residue.h             |   11 +
 include/seqan/basic/basic_simd_vector.h            | 1671 --------------------
 include/seqan/basic/basic_stream.h                 |   23 +-
 include/seqan/basic/debug_test_system.h            |    8 +-
 include/seqan/blast/blast_statistics.h             |   23 +-
 .../graph_algorithms/maximum_weighted_matching.h   |  246 +++
 include/seqan/index/index_bifm_stree.h             |    3 +
 .../seqan/index/index_fm_rank_dictionary_levels.h  |   10 -
 include/seqan/index/index_fm_stree.h               |   17 +-
 include/seqan/index/index_sa_stree.h               |    6 +-
 .../journaled_string_tree_traverser.h              |   12 +
 include/seqan/platform.h                           |   67 +-
 include/seqan/reduced_aminoacid.h                  |   17 +-
 .../reduced_aminoacid_buchfink11_base.h            |  123 ++
 .../reduced_aminoacid_buchfink11_tables.h          |  155 ++
 .../reduced_aminoacid_cannata10_base.h             |  120 ++
 .../reduced_aminoacid_cannata10_tables.h           |  154 ++
 .../reduced_aminoacid_li10_base.h                  |  120 ++
 .../reduced_aminoacid_li10_tables.h                |  154 ++
 .../reduced_aminoacid_murphy5_base.h               |  115 ++
 .../reduced_aminoacid_murphy5_tables.h             |  149 ++
 .../reduced_aminoacid_solis10_base.h               |  120 ++
 .../reduced_aminoacid_solis10_tables.h             |  154 ++
 include/seqan/score.h                              |    1 +
 include/seqan/score/score_simd_wrapper.h           |   41 +-
 include/seqan/simd.h                               |  124 ++
 include/seqan/simd/simd_base.h                     |  319 ++++
 include/seqan/simd/simd_base_seqan_impl.h          |  143 ++
 include/seqan/simd/simd_base_seqan_impl_avx2.h     | 1440 +++++++++++++++++
 include/seqan/simd/simd_base_seqan_impl_sse4.2.h   |  978 ++++++++++++
 include/seqan/simd/simd_base_seqan_interface.h     |  389 +++++
 include/seqan/simd/simd_base_umesimd_impl.h        |  602 +++++++
 include/seqan/stream/iostream_bgzf.h               |    8 +-
 include/seqan/stream/tokenization.h                |   21 +-
 include/seqan/version.h                            |    4 +-
 .../Infrastructure/Use/CustomBuildSystem.rst       |   15 +
 .../DataStructures/Sequence/StringsAndSegments.rst |    2 +-
 .../Tutorial/GettingStarted/AFirstExample.rst      |   33 +-
 .../GettingStarted/BackgroundAndMotivation.rst     |    2 +-
 manual/source/seqan.bib                            |   11 -
 tests/align/CMakeLists.txt                         |    3 +-
 tests/bam_io/test_bam_index.h                      |    2 +
 tests/basic/CMakeLists.txt                         |    7 -
 tests/basic/test_basic_simd_vector.h               |  155 --
 tests/blast/test_blast_output.h                    |    2 +-
 tests/index/test_index_stree_iterators.cpp         |    1 +
 tests/index/test_stree_iterators.h                 |   18 +
 .../test_journaled_string_tree_traverser.cpp       |    1 +
 .../test_journaled_string_tree_traverser.h         |   16 +
 tests/reduced_aminoacid/test_reduced_aminoacid.cpp |    5 +
 tests/reduced_aminoacid/test_reduced_aminoacid.h   |   95 ++
 tests/simd/CMakeLists.txt                          |   48 +
 .../test_simd_vector.cpp}                          |   28 +-
 tests/simd/test_simd_vector.h                      |  953 +++++++++++
 util/cmake/FindSDE.cmake                           |   81 +
 util/cmake/FindUmesimd.cmake                       |   65 +
 util/cmake/SeqAnBuildSystem.cmake                  |   52 +-
 util/cmake/SeqAnContribs.cmake                     |    2 +-
 util/cmake/SeqAnSimdUtility.cmake                  |  611 +++++++
 98 files changed, 8249 insertions(+), 2253 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f3126f1..fc06439 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -75,7 +75,10 @@ set (SEQAN_CTD_EXECUTABLES CACHE INTERNAL "Global list of executables for workfl
 
 option (SEQAN_STATIC_APPS "Build static apps." OFF)
 option (SEQAN_ARCH_SSE4 "Build SSE optimized binaries." OFF)
-option (SEQAN_ARCH_AVX2 "Build AVX optimized binaries." OFF)
+option (SEQAN_ARCH_AVX2 "Build AVX2 optimized binaries." OFF)
+option (SEQAN_ARCH_AVX512_KNL "Build AVX512 optimized binaries for Knights Landing." OFF)
+option (SEQAN_ARCH_AVX512_SKX "Build AVX512 optimized binaries for Skylake." OFF)
+option (SEQAN_ARCH_AVX512_CNL "Build AVX512 optimized binaries for Cannon Lake." OFF)
 option (SEQAN_ARCH_NATIVE "Build natively optimized binaries." OFF)
 
 # ===========================================================================
diff --git a/apps/mason2/mason_options.cpp b/apps/mason2/mason_options.cpp
index 6742317..79415a3 100644
--- a/apps/mason2/mason_options.cpp
+++ b/apps/mason2/mason_options.cpp
@@ -335,12 +335,12 @@ void MaterializerOptions::addOptions(seqan::ArgumentParser & parser) const
 
     addOption(parser, seqan::ArgParseOption("ir", "input-reference", "Path to FASTA file to read the reference from.",
                                             seqan::ArgParseOption::INPUT_FILE, "IN.fa"));
-    setValidValues(parser, "input-reference", "fa fasta");
+    setValidValues(parser, "input-reference", seqan::SeqFileIn::getFileExtensions());
     setRequired(parser, "input-reference");
 
     addOption(parser, seqan::ArgParseOption("iv", "input-vcf", "Path to the VCF file with variants to apply.",
                                             seqan::ArgParseOption::INPUT_FILE, "IN.vcf"));
-    setValidValues(parser, "input-vcf", "vcf");
+    setValidValues(parser, "input-vcf", seqan::VcfFileIn::getFileExtensions());
 }
 
 // ----------------------------------------------------------------------------
@@ -700,12 +700,12 @@ void IlluminaSequencingOptions::addOptions(seqan::ArgumentParser & parser) const
     addOption(parser, seqan::ArgParseOption("", "illumina-left-template-fastq",
                                             "FASTQ file to use for a template for left-end reads.",
                                             seqan::ArgParseOption::INPUT_FILE, "IN.fq"));
-    setValidValues(parser, "illumina-left-template-fastq", "fq fastq fq.gz fastq.gz");
+    setValidValues(parser, "illumina-left-template-fastq", seqan::SeqFileIn::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("", "illumina-right-template-fastq",
                                             "FASTQ file to use for a template for right-end reads.",
                                             seqan::ArgParseOption::INPUT_FILE, "IN.fq"));
-    setValidValues(parser, "illumina-right-template-fastq", "fq fastq fq.gz fastq.gz");
+    setValidValues(parser, "illumina-right-template-fastq", seqan::SeqFileIn::getFileExtensions());
 }
 
 // ----------------------------------------------------------------------------
@@ -1113,20 +1113,20 @@ void MasonSimulatorOptions::addOptions(seqan::ArgumentParser & parser) const
 
     addOption(parser, seqan::ArgParseOption("", "meth-fasta-in", "FASTA file with methylation levels of the input file.",
                                             seqan::ArgParseOption::INPUT_FILE, "IN"));
-    setValidValues(parser, "meth-fasta-in", "fa fasta");
+    setValidValues(parser, "meth-fasta-in", seqan::SeqFileIn::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("o", "out", "Output of single-end/left end reads.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "OUT"));
     setRequired(parser, "out");
-    setValidValues(parser, "out", "fa fasta fq fastq fq.gz fastq.gz");
+    setValidValues(parser, "out", seqan::SeqFileOut::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("or", "out-right", "Output of right reads.  Giving this options enables "
                                             "paired-end simulation.", seqan::ArgParseOption::OUTPUT_FILE, "OUT2"));
-    setValidValues(parser, "out-right", "fa fasta fq fastq fq.gz fastq.gz");
+    setValidValues(parser, "out-right", seqan::SeqFileOut::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("oa", "out-alignment", "SAM/BAM file with alignments.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "OUT"));
-    setValidValues(parser, "out-alignment", "sam bam");
+    setValidValues(parser, "out-alignment", seqan::BamFileOut::getFileExtensions());
 
     // Add options of the component options.
     matOptions.addOptions(parser);
@@ -1315,7 +1315,7 @@ void MasonMaterializerOptions::addOptions(seqan::ArgumentParser & parser) const
     addOption(parser, seqan::ArgParseOption("o", "out", "Output of materialized contigs.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "OUT"));
     setRequired(parser, "out");
-    setValidValues(parser, "out", "fa fasta");
+    setValidValues(parser, "out", seqan::SeqFileOut::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("", "out-breakpoints", "TSV file to write breakpoints in variants to.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "TSV"));
@@ -1328,11 +1328,11 @@ void MasonMaterializerOptions::addOptions(seqan::ArgumentParser & parser) const
 
     addOption(parser, seqan::ArgParseOption("", "meth-fasta-in", "FASTA file with methylation levels of the input file.",
                                             seqan::ArgParseOption::INPUT_FILE, "IN"));
-    setValidValues(parser, "meth-fasta-in", "fa fasta");
+    setValidValues(parser, "meth-fasta-in", seqan::SeqFileIn::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("", "meth-fasta-out", "FASTA file with methylation levels of the output file.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "OUT"));
-    setValidValues(parser, "meth-fasta-out", "fa fasta");
+    setValidValues(parser, "meth-fasta-out", seqan::SeqFileOut::getFileExtensions());
 
     // Add options of the component options.
     matOptions.addOptions(parser);
@@ -1429,7 +1429,7 @@ void MasonSplicingOptions::addOptions(seqan::ArgumentParser & parser) const
     addOption(parser, seqan::ArgParseOption("o", "out", "Output of materialized contigs.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "OUT"));
     setRequired(parser, "out");
-    setValidValues(parser, "out", "fa fasta");
+    setValidValues(parser, "out", seqan::SeqFileOut::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("", "haplotype-name-sep",
                                             "String separating contig name from haplotype number.",
@@ -1439,7 +1439,7 @@ void MasonSplicingOptions::addOptions(seqan::ArgumentParser & parser) const
     addOption(parser, seqan::ArgParseOption("ig", "in-gff", "Path to input GFF or GTF file, must be "
                                             "sorted by reference name.",
                                             seqan::ArgParseOption::INPUT_FILE, "IN.gff"));
-    setValidValues(parser, "in-gff", "gff gtf");
+    setValidValues(parser, "in-gff", seqan::GffFileIn::getFileExtensions());
     setRequired(parser, "in-gff");
 
     addOption(parser, seqan::ArgParseOption("", "gff-type", "Splicing will filter to the records that have this type.",
@@ -1533,18 +1533,18 @@ void MasonFragmentSequencingOptions::addOptions(seqan::ArgumentParser & parser)
     setDefaultValue(parser, "seed", "0");
 
     addOption(parser, seqan::ArgParseOption("i", "in", "Path to input file.",
-                                            seqan::ArgParseOption::INPUT_FILE, "OUT"));
+                                            seqan::ArgParseOption::INPUT_FILE, "IN"));
     setRequired(parser, "in");
-    setValidValues(parser, "in", "fa fasta");
+    setValidValues(parser, "in", seqan::SeqFileIn::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("o", "out", "Output of single-end/left end reads.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "OUT"));
     setRequired(parser, "out");
-    setValidValues(parser, "out", "fa fasta fq fastq fq.gz fastq.gz");
+    setValidValues(parser, "out", seqan::SeqFileOut::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("or", "out-right", "Output of right reads.  Giving this options enables "
                                             "paired-end simulation.", seqan::ArgParseOption::OUTPUT_FILE, "OUT2"));
-    setValidValues(parser, "out-right", "fa fasta fq fastq fq.gz fastq.gz");
+    setValidValues(parser, "out-right", seqan::SeqFileOut::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("", "force-single-end", "Force single-end simulation although --out-right "
                                             "is given."));
@@ -1651,12 +1651,12 @@ void MasonMethylationOptions::addOptions(seqan::ArgumentParser & parser) const
     addOption(parser, seqan::ArgParseOption("i", "in", "Input FASTA file with genome.",
                                             seqan::ArgParseOption::INPUT_FILE, "IN.fa"));
     setRequired(parser, "in");
-    setValidValues(parser, "in", "fa fasta");
+    setValidValues(parser, "in", seqan::SeqFileIn::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("o", "out", "Input FASTA file with genome.",
                                             seqan::ArgParseOption::INPUT_FILE, "OUT.fa"));
     setRequired(parser, "out");
-    setValidValues(parser, "out", "fa fasta");
+    setValidValues(parser, "out", seqan::SeqFileOut::getFileExtensions());
 
     // Add options of the component options.
     methOptions.addOptions(parser);
diff --git a/apps/mason2/mason_options.h b/apps/mason2/mason_options.h
index 8d68330..0e26e69 100644
--- a/apps/mason2/mason_options.h
+++ b/apps/mason2/mason_options.h
@@ -50,6 +50,10 @@
 
 #include <seqan/arg_parse.h>
 #include <seqan/sequence.h>
+#include <seqan/seq_io.h>
+#include <seqan/bam_io.h>
+#include <seqan/gff_io.h>
+#include <seqan/vcf_io.h>
 
 #include "mason_types.h"
 
diff --git a/apps/mason2/vcf_materialization.cpp b/apps/mason2/vcf_materialization.cpp
index 6e3dc5f..c7cbee0 100644
--- a/apps/mason2/vcf_materialization.cpp
+++ b/apps/mason2/vcf_materialization.cpp
@@ -484,6 +484,8 @@ void VcfMaterializer::_appendToVariants(Variants & variants, seqan::VcfRecord co
         seqan::CharString buffer;
         snpRecord.haplotype = 0;
         for (; !atEnd(inputIter); ++inputIter)
+        {
+            if (*inputIter == ':') break;
             if ((*inputIter == '|' || *inputIter == '/'))
             {
                 if (!empty(buffer))
@@ -504,6 +506,7 @@ void VcfMaterializer::_appendToVariants(Variants & variants, seqan::VcfRecord co
             {
                 appendValue(buffer, *inputIter);
             }
+        }
         if (!empty(buffer))
         {
             unsigned idx = std::min(seqan::lexicalCast<unsigned>(buffer),
@@ -522,8 +525,8 @@ void VcfMaterializer::_appendToVariants(Variants & variants, seqan::VcfRecord co
         smallIndel.rId = vcfRecord.rID;
         smallIndel.pos = vcfRecord.beginPos + 1;
 
-        SEQAN_ASSERT_NOT(contains(vcfRecord.alt, ","));  // only one alternative
-        SEQAN_ASSERT((length(vcfRecord.alt) == 1u) != (length(vcfRecord.ref) == 1u));  // XOR
+        if (contains(vcfRecord.alt, ",")) return;  // only one alternative
+        if (length(vcfRecord.alt) > 1u && length(vcfRecord.ref) > 1u) return; // skip MNP and COMPLEX variants
 
         smallIndel.haplotype = 0;
         if (length(vcfRecord.ref) == 1u)  // insertion
diff --git a/apps/micro_razers/micro_razers.cpp b/apps/micro_razers/micro_razers.cpp
index 439bae4..6cf9ff3 100644
--- a/apps/micro_razers/micro_razers.cpp
+++ b/apps/micro_razers/micro_razers.cpp
@@ -212,6 +212,7 @@ int main(int argc, const char *argv[])
     
     
     ArgumentParser parser("micro_razers");
+    setShortDescription(parser, "Map small RNA reads possibly containing 3' adapter sequence");
     addUsageLine(parser, "[\\fIOPTIONS\\fP] <\\fIGENOME FILE\\fP> <\\fIREADS FILE\\fP>");
     addDescription(parser, "MicroRazerS uses a prefix-based mapping strategy to map "
                            "small RNA reads possibly containing 3' adapter sequence. ");
diff --git a/apps/seqan_tcoffee/README b/apps/seqan_tcoffee/README
index 2828c19..0f823a7 100644
--- a/apps/seqan_tcoffee/README
+++ b/apps/seqan_tcoffee/README
@@ -16,25 +16,23 @@ Table of Contents
 
 SeqAn::T-Coffee is distributed with SeqAn, http://www.seqan.de. 
 You can build it using the latest snapshot or directly from
-the SVN repository.
+the Github repository.
 
 Snapshot:
 
-  1)  Download the latest snapshot of SeqAn
+  1)  Download the latest snapshot of SeqAn::T-Coffee (http://packages.seqan.de/seqan_tcoffee/)
   2)  Unzip it to a directory of your choice (e.g. snapshot)
-  3)  cd snapshot/apps
-  4)  make seqan_tcoffee
-  5)  cd seqan_tcoffee
-  6)  ./seqan_tcoffee --help
+  3)  cd snapshot/bin
+  4)  ./seqan_tcoffee --help
 
-SVN:
+Git:
 
-  1)  svn co http://svn.mi.fu-berlin.de/seqan/trunk/seqan
-  2)  cd seqan
-  3)  make forwards
-  4)  cd projects/library/apps
+  1)  git clone https://github.com/seqan/seqan.git
+  2)  mkdir seqan_build
+  3)  cd seqan_build
+  4)  cmake ../seqan
   5)  make seqan_tcoffee
-  6)  cd seqan_tcoffee
+  6)  cd bin
   7)  ./seqan_tcoffee --help
 
 ---------------------------------------------------------------------------
diff --git a/apps/seqan_tcoffee/seqan_tcoffee.cpp b/apps/seqan_tcoffee/seqan_tcoffee.cpp
index 2c62438..0446550 100644
--- a/apps/seqan_tcoffee/seqan_tcoffee.cpp
+++ b/apps/seqan_tcoffee/seqan_tcoffee.cpp
@@ -17,6 +17,8 @@ Lesser General Public License for more details.
 
 //#define SEQAN_TCOFFEE_DEBUG
 
+#include <cstdlib>
+
 #include <seqan/basic.h>
 #include <seqan/graph_msa.h>
 #include <seqan/modifier.h>
@@ -67,7 +69,16 @@ customizedMsaAlignment(MsaOptions<TAlphabet, TScore> const& msaOpt)
     Graph<Alignment<StringSet<TSequence, Dependent<> >, void, WithoutEdgeId> > gAlign;
 
     // MSA
-    globalMsaAlignment(gAlign, sequenceSet, sequenceNames, msaOpt);
+    try
+    {
+        globalMsaAlignment(gAlign, sequenceSet, sequenceNames, msaOpt);
+    }
+    catch (const std::bad_alloc & exception)
+    {
+        std::cerr << "Allocation for globalAlignment failed. Use smaller data or try a seeded alignment. \n"
+                  << exception.what() << std::endl;
+        std::exit(EXIT_FAILURE);
+    }
 
     // Alignment output
     TOutStream outStream;
@@ -323,6 +334,26 @@ _initScoreMatrix(ArgumentParser& parser, Rna5 const)
 //////////////////////////////////////////////////////////////////////////////////
 
 inline void
+_initScoreMatrix(ArgumentParser& parser, Iupac const)
+{
+    String<char> matrix;
+    getOptionValue(matrix, parser, "matrix");
+    if (isSet(parser, "matrix"))
+    {
+        Score<int, ScoreMatrix<> > sc;
+        loadScoreMatrix(sc, toCString(matrix));
+        _initMsaParams<Iupac>(parser, sc);
+    }
+    else
+    {
+        Score<int> sc;
+        _initMsaParams<Iupac>(parser, sc);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////////
+
+inline void
 _initScoreMatrix(ArgumentParser& parser, AminoAcid const)
 {
     String<char> matrix;
@@ -359,7 +390,7 @@ _setUpArgumentParser(ArgumentParser & parser)
     setValidValues(parser, "seq", getFileExtensions(Fasta()));  // allow only fasta files as input
 
     addOption(parser, ArgParseOption("a", "alphabet", "The used sequence alphabet.", ArgParseArgument::STRING));
-    setValidValues(parser, "alphabet", "protein dna rna");
+    setValidValues(parser, "alphabet", "protein dna rna iupac");
     setDefaultValue(parser, "alphabet", "protein");
 
     addOption(parser, ArgParseOption("o", "outfile", "Name of the output file.", ArgParseArgument::OUTPUT_FILE));
@@ -500,6 +531,8 @@ int main(int argc, const char *argv [])
         _initScoreMatrix(parser, Dna5());
     else if (alphabet == "rna")
         _initScoreMatrix(parser, Rna5());
+    else if (alphabet == "iupac")
+        _initScoreMatrix(parser, Iupac());
     else
         _initScoreMatrix(parser, AminoAcid());
 
diff --git a/apps/sgip/sgip.cpp b/apps/sgip/sgip.cpp
index e2067e8..bb4d9a7 100755
--- a/apps/sgip/sgip.cpp
+++ b/apps/sgip/sgip.cpp
@@ -168,7 +168,7 @@ template <typename TParser>
 void _setupParser(TParser & parser)
 {
     setVersion(parser, SEQAN_APP_VERSION " [" SEQAN_REVISION "]");
-    addDescription(parser, " SGIP - Solution of Graph Isomorphism Problem");
+    setShortDescription(parser, "Solution of Graph Isomorphism Problem");
     addUsageLine(parser, "-o <original graph> [Option]");    
     addSection(parser, "Mandatory Options");
     addOption(parser, ArgParseOption("o", "original", "File containing original graph", ArgParseArgument::INPUT_FILE,"IN"));
diff --git a/apps/splazers/splazers.cpp b/apps/splazers/splazers.cpp
index 433b4f4..61dd6fc 100644
--- a/apps/splazers/splazers.cpp
+++ b/apps/splazers/splazers.cpp
@@ -303,6 +303,7 @@ int main(int argc, const char *argv[])
 #ifdef RAZERS_MATEPAIRS
 	addUsageLine(parser, "[\\fIOPTIONS\\fP] <\\fIGENOME FILE\\fP> <\\fIREADS FILE 1\\fP> <\\fIREADS FILE 2\\fP>");
 #endif
+    setShortDescription(parser, "Split-map read sequences");
     addDescription(parser,
             "SplazerS uses a prefix-suffix mapping strategy to split-map read sequences."
             "If a SAM file of mapped reads is given as input, all unmapped but anchored"
diff --git a/demos/tutorial/a_first_example/final_result.cpp b/demos/tutorial/a_first_example/final_result.cpp
index 4311488..5fd0974 100644
--- a/demos/tutorial/a_first_example/final_result.cpp
+++ b/demos/tutorial/a_first_example/final_result.cpp
@@ -1,4 +1,3 @@
-//![result]
 #include <iostream>
 #include <seqan/file.h>
 #include <seqan/sequence.h>
@@ -98,36 +97,33 @@ void print(TText const & score, GreaterZero const & /*tag*/)
 
 int main()
 {
-    String<char> text = "This is an awesome tutorial to get to now SeqAn!";
+    String<char> text = "This is an awesome tutorial to get to know SeqAn!";
     String<char> pattern = "tutorial";
     String<int> score = computeScore(text, pattern);
 
     print(text);
-    // > This is an awesome tutorial to get to now SeqAn!
+
     print(pattern);
-    // > tutorial
+
     print(score);
-    // > 1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0
+
     print(score, MaxOnly());
-    // > 19
+
     print(score, GreaterZero());
-    // > (2; 1) (5; 1) (12; 1) (17; 1) (19; 8) (21; 1) (26; 2) (28; 1) (31; 1) (33; 3) (35; 1) (36; 1)
 
     // And now for a protein pattern
     String<AminoAcid> protein = "tutorial";
     String<int> proteinScore = computeScore(text, protein);
 
     print(text);
-    // > This is an awesome tutorial to get to now SeqAn!
+
     print(protein);
-    // > TXTXRIAL
+
     print(proteinScore);
-    // > 6 -9 -3 -6 -6 0 -9 -8 -7 -3 -9 -5 -8 -4 -5 -6 -6 1 -6 25 -7 2 -6 -6 -9 -6 -5 -7 1 -7 -5 -4 -6 2 -6 -3 -8 -9 -10 -4 -6 0 0 0 0 0 0 0
+
     print(proteinScore, MaxOnly());
-    // > 19
+
     print(proteinScore, GreaterZero());
-    // > (17; 1) (19; 25) (21; 2) (28; 1) (33; 2)
 
     return 0;
 }
-//![result]
diff --git a/demos/tutorial/a_first_example/final_result.cpp.stdout b/demos/tutorial/a_first_example/final_result.cpp.stdout
index 5558d1a..da7f9ec 100644
--- a/demos/tutorial/a_first_example/final_result.cpp.stdout
+++ b/demos/tutorial/a_first_example/final_result.cpp.stdout
@@ -1,10 +1,11 @@
-This is an awesome tutorial to get to now SeqAn!
+This is an awesome tutorial to get to know SeqAn!
 tutorial
-1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0 
+1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 0 1 0 0 0 0 
 19 
-(2; 1) (5; 1) (12; 1) (17; 1) (19; 8) (21; 1) (26; 2) (28; 1) (31; 1) (33; 3) (35; 1) (36; 1) 
-This is an awesome tutorial to get to now SeqAn!
+(2; 1) (5; 1) (12; 1) (17; 1) (19; 8) (21; 1) (26; 2) (28; 1) (31; 1) (33; 3) (35; 1) (37; 1) 
+This is an awesome tutorial to get to know SeqAn!
 TUTORIAL
-6 -9 -3 -6 -6 0 -9 -8 -7 -3 -9 -5 -8 -4 -5 -6 -6 1 -6 25 -7 2 -6 -6 -9 -6 -5 -7 1 -7 -5 -4 -6 2 -6 -3 -8 -9 -10 -4 -6 
+6 -9 -3 -6 -6 0 -9 -8 -7 -3 -9 -5 -8 -4 -5 -6 -6 1 -6 25 -7 2 -6 -6 -9 -6 -5 -7 1 -7 -5 -3 -7 1 -4 -2 -9 -8 -10 -10 -4 -6 
 19 
-(17; 1) (19; 25) (21; 2) (28; 1) (33; 2) 
+(17; 1) (19; 25) (21; 2) (28; 1) (33; 1) 
+
diff --git a/demos/tutorial/a_first_example/solution_1.cpp b/demos/tutorial/a_first_example/solution_1.cpp
index cfd9e8c..c0c1eda 100755
--- a/demos/tutorial/a_first_example/solution_1.cpp
+++ b/demos/tutorial/a_first_example/solution_1.cpp
@@ -1,5 +1,3 @@
-// Copy the code into a demo program and have a look at the result.
-
 #include <iostream>
 #include <seqan/file.h>
 #include <seqan/sequence.h>
@@ -34,7 +32,5 @@ int main()
         std::cout << score[i] << " ";
     std::cout << std::endl;
 
-    // > 1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 0 1 0 0 0 0
-
     return 0;
 }
diff --git a/demos/tutorial/a_first_example/solution_2.cpp b/demos/tutorial/a_first_example/solution_2.cpp
index 47cc2ba..453fd05 100644
--- a/demos/tutorial/a_first_example/solution_2.cpp
+++ b/demos/tutorial/a_first_example/solution_2.cpp
@@ -1,5 +1,4 @@
-// Copy the code into your current file and encapsulate the print instructions.
-
+//![all]
 #include <iostream>
 #include <seqan/file.h>
 #include <seqan/sequence.h>
@@ -38,7 +37,7 @@ void print(String<int> text)
 
 int main()
 {
-    String<char> text = "This is an awesome tutorial to get to now SeqAn!";
+    String<char> text = "This is an awesome tutorial to get to know SeqAn!";
     String<char> pattern = "tutorial";
     String<int> score = computeScore(text, pattern);
 
@@ -46,3 +45,4 @@ int main()
 
     return 0;
 }
+//![all]
diff --git a/demos/tutorial/a_first_example/solution_2.cpp.stdout b/demos/tutorial/a_first_example/solution_2.cpp.stdout
index 76bbad7..b4d9330 100644
--- a/demos/tutorial/a_first_example/solution_2.cpp.stdout
+++ b/demos/tutorial/a_first_example/solution_2.cpp.stdout
@@ -1 +1 @@
-1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0 
+1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 0 1 0 0 0 0 
diff --git a/demos/tutorial/a_first_example/solution_3.cpp b/demos/tutorial/a_first_example/solution_3.cpp
index b290300..119ab74 100644
--- a/demos/tutorial/a_first_example/solution_3.cpp
+++ b/demos/tutorial/a_first_example/solution_3.cpp
@@ -1,5 +1,4 @@
-// Adjust your current code to be more memory and time efficient by using references in the function header.
-
+//![all]
 #include <iostream>
 #include <seqan/file.h>
 #include <seqan/sequence.h>
@@ -40,7 +39,7 @@ void print(String<int> const & text)
 
 int main()
 {
-    String<char> text = "This is an awesome tutorial to get to now SeqAn!";
+    String<char> text = "This is an awesome tutorial to get to know SeqAn!";
     String<char> pattern = "tutorial";
     String<int> score = computeScore(text, pattern);
 
@@ -48,3 +47,4 @@ int main()
 
     return 0;
 }
+//![all]
diff --git a/demos/tutorial/a_first_example/solution_3.cpp.stdout b/demos/tutorial/a_first_example/solution_3.cpp.stdout
index 76bbad7..b4d9330 100644
--- a/demos/tutorial/a_first_example/solution_3.cpp.stdout
+++ b/demos/tutorial/a_first_example/solution_3.cpp.stdout
@@ -1 +1 @@
-1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0 
+1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 0 1 0 0 0 0 
diff --git a/demos/tutorial/a_first_example/solution_4.cpp b/demos/tutorial/a_first_example/solution_4.cpp
index ee15b74..1eb50dc 100644
--- a/demos/tutorial/a_first_example/solution_4.cpp
+++ b/demos/tutorial/a_first_example/solution_4.cpp
@@ -1,5 +1,3 @@
-// Generalize the computeLocalScore function in you file.
-
 #include <iostream>
 #include <seqan/file.h>
 #include <seqan/sequence.h>
@@ -39,7 +37,7 @@ void print(String<int> const & text)
 
 int main()
 {
-    String<char> text = "This is an awesome tutorial to get to now SeqAn!";
+    String<char> text = "This is an awesome tutorial to get to know SeqAn!";
     String<char> pattern = "tutorial";
     String<int> score = computeScore(text, pattern);
     print(score);
diff --git a/demos/tutorial/a_first_example/solution_4.cpp.stdout b/demos/tutorial/a_first_example/solution_4.cpp.stdout
index 76bbad7..a6c38cf 100644
--- a/demos/tutorial/a_first_example/solution_4.cpp.stdout
+++ b/demos/tutorial/a_first_example/solution_4.cpp.stdout
@@ -1 +1,2 @@
-1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0 
+1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 0 1 0 0 0 0 
+
diff --git a/demos/tutorial/a_first_example/solution_4_templateSubclassing.cpp b/demos/tutorial/a_first_example/solution_4_templateSubclassing.cpp
index 34cdbd7..180ddc6 100644
--- a/demos/tutorial/a_first_example/solution_4_templateSubclassing.cpp
+++ b/demos/tutorial/a_first_example/solution_4_templateSubclassing.cpp
@@ -1,5 +1,3 @@
-// Generalize the computeLocalScore function in you file.
-
 #include <iostream>
 #include <seqan/file.h>
 #include <seqan/sequence.h>
diff --git a/demos/tutorial/a_first_example/solution_5.cpp b/demos/tutorial/a_first_example/solution_5.cpp
index ec3f084..7801253 100644
--- a/demos/tutorial/a_first_example/solution_5.cpp
+++ b/demos/tutorial/a_first_example/solution_5.cpp
@@ -1,5 +1,3 @@
-// Provide a generic print function which is used when the input type is not String<int>.
-
 #include <iostream>
 #include <seqan/file.h>
 #include <seqan/sequence.h>
@@ -55,15 +53,15 @@ void print(String<int> const & text)
 
 int main()
 {
-    String<char> text = "This is an awesome tutorial to get to now SeqAn!";
+    String<char> text = "This is an awesome tutorial to get to know SeqAn!";
     String<char> pattern = "tutorial";
     String<int> score = computeScore(text, pattern);
 
     print(text);
-    // > This is an awesome tutorial to get to now SeqAn!
+
     print(pattern);
-    // > tutorial
+
     print(score);
-    // > 1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0
+
     return 0;
 }
diff --git a/demos/tutorial/a_first_example/solution_5.cpp.stdout b/demos/tutorial/a_first_example/solution_5.cpp.stdout
index 9d0b9b8..c78c95e 100644
--- a/demos/tutorial/a_first_example/solution_5.cpp.stdout
+++ b/demos/tutorial/a_first_example/solution_5.cpp.stdout
@@ -1,3 +1,3 @@
-This is an awesome tutorial to get to now SeqAn!
+This is an awesome tutorial to get to know SeqAn!
 tutorial
-1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0 
+1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 0 1 0 0 0 0 
diff --git a/demos/tutorial/a_first_example/solution_6.cpp b/demos/tutorial/a_first_example/solution_6.cpp
index fde568e..9698125 100644
--- a/demos/tutorial/a_first_example/solution_6.cpp
+++ b/demos/tutorial/a_first_example/solution_6.cpp
@@ -99,35 +99,33 @@ void print(TText const & score, GreaterZero const & /*tag*/)
 
 int main()
 {
-    String<char> text = "This is an awesome tutorial to get to now SeqAn!";
+    String<char> text = "This is an awesome tutorial to get to know SeqAn!";
     String<char> pattern = "tutorial";
     String<int> score = computeScore(text, pattern);
 
     print(text);
-    // > This is an awesome tutorial to get to now SeqAn!
+
     print(pattern);
-    // > tutorial
+
     print(score);
-    // > 1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0
+
     print(score, MaxOnly());
-    // > 19
+
     print(score, GreaterZero());
-    // > (2; 1) (5; 1) (12; 1) (17; 1) (19; 8) (21; 1) (26; 2) (28; 1) (31; 1) (33; 3) (35; 1) (36; 1)
 
     // And now for a protein pattern
     String<AminoAcid> protein = "tutorial";
     String<int> proteinScore = computeScore(text, protein);
 
     print(text);
-    // > This is an awesome tutorial to get to now SeqAn!
+
     print(protein);
-    // > TXTXRIAL
+
     print(proteinScore);
-    // > 6 -9 -3 -6 -6 0 -9 -8 -7 -3 -9 -5 -8 -4 -5 -6 -6 1 -6 25 -7 2 -6 -6 -9 -6 -5 -7 1 -7 -5 -4 -6 2 -6 -3 -8 -9 -10 -4 -6 0 0 0 0 0 0 0
+
     print(proteinScore, MaxOnly());
-    // > 19
+
     print(proteinScore, GreaterZero());
-    // > (17; 1) (19; 25) (21; 2) (28; 1) (33; 2)
 
     return 0;
 }
diff --git a/demos/tutorial/a_first_example/solution_6.cpp.stdout b/demos/tutorial/a_first_example/solution_6.cpp.stdout
index 5558d1a..363634d 100644
--- a/demos/tutorial/a_first_example/solution_6.cpp.stdout
+++ b/demos/tutorial/a_first_example/solution_6.cpp.stdout
@@ -1,10 +1,10 @@
-This is an awesome tutorial to get to now SeqAn!
+This is an awesome tutorial to get to know SeqAn!
 tutorial
-1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 1 0 0 0 0 
+1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 8 0 1 0 0 0 0 2 0 1 0 0 1 0 3 0 1 0 1 0 0 0 0 
 19 
-(2; 1) (5; 1) (12; 1) (17; 1) (19; 8) (21; 1) (26; 2) (28; 1) (31; 1) (33; 3) (35; 1) (36; 1) 
-This is an awesome tutorial to get to now SeqAn!
+(2; 1) (5; 1) (12; 1) (17; 1) (19; 8) (21; 1) (26; 2) (28; 1) (31; 1) (33; 3) (35; 1) (37; 1) 
+This is an awesome tutorial to get to know SeqAn!
 TUTORIAL
-6 -9 -3 -6 -6 0 -9 -8 -7 -3 -9 -5 -8 -4 -5 -6 -6 1 -6 25 -7 2 -6 -6 -9 -6 -5 -7 1 -7 -5 -4 -6 2 -6 -3 -8 -9 -10 -4 -6 
+6 -9 -3 -6 -6 0 -9 -8 -7 -3 -9 -5 -8 -4 -5 -6 -6 1 -6 25 -7 2 -6 -6 -9 -6 -5 -7 1 -7 -5 -3 -7 1 -4 -2 -9 -8 -10 -10 -4 -6 
 19 
-(17; 1) (19; 25) (21; 2) (28; 1) (33; 2) 
+(17; 1) (19; 25) (21; 2) (28; 1) (33; 1) 
diff --git a/demos/tutorial/blast_io/write_assignment.cpp b/demos/tutorial/blast_io/write_assignment.cpp
index 0607186..6bc9780 100644
--- a/demos/tutorial/blast_io/write_assignment.cpp
+++ b/demos/tutorial/blast_io/write_assignment.cpp
@@ -88,12 +88,11 @@ int main(int argc, char ** argv)
             m.sStart = beginPosition(m.alignRow1);
             m.sEnd   = endPosition(m.alignRow1);
 
-            m.qLength = length(queries[q]);
             m.sLength = length(subjects[s]);
 
             computeAlignmentStats(m, context(outfile));
             computeBitScore(m, context(outfile));
-            computeEValue(m, context(outfile));
+            computeEValue(m, r.qLength, context(outfile));
 
             if (m.eValue > 1)
                 eraseBack(records[q].matches);
diff --git a/demos/tutorial/iterators/assignment_1_solution.cpp b/demos/tutorial/iterators/assignment_1_solution.cpp
index b46682b..93fb8a9 100644
--- a/demos/tutorial/iterators/assignment_1_solution.cpp
+++ b/demos/tutorial/iterators/assignment_1_solution.cpp
@@ -13,8 +13,8 @@ int main()
 
     for (; it != itEnd; goNext(it))
     {
-        if (getValue(it) == 'N')
-            value(it) = 'A';
+        if (*it == 'N')
+            *it = 'A';
     }
     std::cout << "Modified genome: " << genome << std::endl;
     return 0;
diff --git a/demos/tutorial/sequences/base.cpp b/demos/tutorial/sequences/base.cpp
index 5bd6f0a..64d2b38 100644
--- a/demos/tutorial/sequences/base.cpp
+++ b/demos/tutorial/sequences/base.cpp
@@ -44,11 +44,11 @@ int main()
 
     Dna5String genome = "ATGGTTTCAACGTAATGCTGAACATGTCGCGT";
     Dna5String read = "TGGTNTCA";
-    Dna5String genomeFragment;
     unsigned beginPosition = 1;
 //![assignment5_code_to_change]
     // We have to create a copy of the corresponding fragment of the genome, where the read aligns to
     // Change this piece of code using an infix of the genome
+    Dna5String genomeFragment;
     for (unsigned i = 0; i < length(read); ++i)
     {
         appendValue(genomeFragment, genome[beginPosition + i]);
diff --git a/include/seqan/align.h b/include/seqan/align.h
index 8e5858e..083a08f 100644
--- a/include/seqan/align.h
+++ b/include/seqan/align.h
@@ -53,6 +53,7 @@
 #include <algorithm>
 
 #include <seqan/basic.h>
+#include <seqan/simd.h>
 #include <seqan/modifier.h>  // ModifiedAlphabet<>.
 #include <seqan/align/align_metafunctions.h>
 #include <seqan/graph_align.h>  // TODO(holtgrew): We should not have to depend on this.
diff --git a/include/seqan/align/dp_algorithm_impl.h b/include/seqan/align/dp_algorithm_impl.h
index 39ae3d8..de388f9 100644
--- a/include/seqan/align/dp_algorithm_impl.h
+++ b/include/seqan/align/dp_algorithm_impl.h
@@ -359,6 +359,7 @@ _computeTrack(TDPScout & scout,
     // Compute the inner cells of the current track.
     for (; iter != itEnd; ++iter)
     {
+        _incVerticalPos(scout);
         // Set the iterator to the next cell within the track.
         _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), InnerCell());
         _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), InnerCell());
@@ -382,8 +383,8 @@ _computeTrack(TDPScout & scout,
                          sequenceEntryForScore(scoringScheme, container(iter), position(iter)), scoringScheme,
                          TColumnDescriptor(), InnerCell(), TDPProfile());
         }
-        _incVerticalPos(scout);
     }
+    _incVerticalPos(scout);
     // Set the iterator to the last cell of the track.
     _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), LastCell());
     _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), LastCell());
@@ -458,6 +459,7 @@ _computeUnbandedAlignment(TDPScout & scout,
     TConstSeqHIterator seqHIterEnd = end(seqH, Rooted()) - 1;
     for (; seqHIter != seqHIterEnd; ++seqHIter)
     {
+        _incHorizontalPos(scout);
         // We might only select it if SIMD version is available.
         if (SEQAN_UNLIKELY(_reachedHorizontalEndPoint(scout, seqHIter)))
         {
@@ -480,13 +482,12 @@ _computeUnbandedAlignment(TDPScout & scout,
         {
             return;
         }
-        _incHorizontalPos(scout);
     }
 
     // ============================================================================
     // POSTPROCESSING
     // ============================================================================
-
+    _incHorizontalPos(scout);
     _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
                   sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
                   sequenceEntryForScore(scoringScheme, seqV, 0),
@@ -1374,8 +1375,10 @@ _correctTraceValue(TTraceNavigator & traceNavigator,
                    DPScout_<DPCell_<TScoreValue, AffineGaps>, TDPScoutSpec>  const & dpScout)
 {
     _setToPosition(traceNavigator, maxHostPosition(dpScout));
-    TScoreValue cmpV = cmpEq(_verticalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore));
-    TScoreValue cmpH = cmpEq(_horizontalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore));
+    TScoreValue flag = createVector<TScoreValue>(0);
+    assignValue(flag, dpScout._simdLane, ~static_cast<typename Value<TScoreValue>::Type>(0));
+    TScoreValue cmpV = cmpEq(_verticalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)) & flag;
+    TScoreValue cmpH = cmpEq(_horizontalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)) & flag;
     value(traceNavigator) = blend(value(traceNavigator),
                                   value(traceNavigator) & ~TraceBitMap_<TScoreValue>::DIAGONAL,
                                   cmpV | cmpH);
@@ -1411,8 +1414,10 @@ _correctTraceValue(TTraceNavigator & traceNavigator,
                    DPScout_<DPCell_<TScoreValue, DynamicGaps>, TDPScoutSpec>  const & dpScout)
 {
     _setToPosition(traceNavigator, maxHostPosition(dpScout));
-    TScoreValue cmpV = isGapExtension(dpScout._maxScore, DynamicGapExtensionVertical());
-    TScoreValue cmpH = isGapExtension(dpScout._maxScore, DynamicGapExtensionHorizontal());
+    TScoreValue flag = createVector<TScoreValue>(0);
+    assignValue(flag, dpScout._simdLane, ~static_cast<typename Value<TScoreValue>::Type>(0));
+    TScoreValue cmpV = isGapExtension(dpScout._maxScore, DynamicGapExtensionVertical()) & flag;
+    TScoreValue cmpH = isGapExtension(dpScout._maxScore, DynamicGapExtensionHorizontal()) & flag;
     value(traceNavigator) = blend(value(traceNavigator),
                                   value(traceNavigator) & ~TraceBitMap_<TScoreValue>::DIAGONAL,
                                   cmpV | cmpH);
diff --git a/include/seqan/align/dp_align_simd_helper.h b/include/seqan/align/dp_align_simd_helper.h
index 8fd634a..e24502d 100644
--- a/include/seqan/align/dp_align_simd_helper.h
+++ b/include/seqan/align/dp_align_simd_helper.h
@@ -69,12 +69,13 @@ struct VectorLength_;
 // Tags, Classes, Enums
 // ============================================================================
 
-template <typename TSimdVector_, typename TSeqH_, typename TSeqV_>
+template <typename TSimdVector_, typename TSeqH_, typename TSeqV_, typename TDPProfile_>
 struct SimdAlignVariableLengthTraits
 {
     using TSimdVector   = TSimdVector_;
     using TSeqH         = TSeqH_;
     using TSeqV         = TSeqV_;
+    using TDPProfile    = TDPProfile_;
 };
 
 // ============================================================================
@@ -89,38 +90,27 @@ struct SimdAlignVariableLengthTraits
 // Function _createSimdRepImpl()
 // ----------------------------------------------------------------------------
 
-#define SEQAN_CREATE_SIMD_REP_IMPL_2(data, strPos, chrPos)    getValue(data[strPos + 1], chrPos), getValue(data[strPos], chrPos)
-#define SEQAN_CREATE_SIMD_REP_IMPL_4(data, strPos, chrPos)    SEQAN_CREATE_SIMD_REP_IMPL_2(data, strPos + 2, chrPos),  SEQAN_CREATE_SIMD_REP_IMPL_2(data, strPos, chrPos)
-#define SEQAN_CREATE_SIMD_REP_IMPL_8(data, strPos, chrPos)    SEQAN_CREATE_SIMD_REP_IMPL_4(data, strPos + 4, chrPos),  SEQAN_CREATE_SIMD_REP_IMPL_4(data, strPos, chrPos)
-#define SEQAN_CREATE_SIMD_REP_IMPL_16(data, strPos, chrPos)   SEQAN_CREATE_SIMD_REP_IMPL_8(data, strPos + 8, chrPos),  SEQAN_CREATE_SIMD_REP_IMPL_8(data, strPos, chrPos)
-#define SEQAN_CREATE_SIMD_REP_IMPL_32(data, strPos, chrPos)   SEQAN_CREATE_SIMD_REP_IMPL_16(data, strPos + 16, chrPos), SEQAN_CREATE_SIMD_REP_IMPL_16(data, strPos, chrPos)
-
-#define SEQAN_CREATE_SIMD_REP_FILL_IMPL_2(MACRO, data, chrPos) MACRO(data, 0, chrPos)
-#define SEQAN_CREATE_SIMD_REP_FILL_IMPL(data, chrPos, SIZE) SEQAN_CREATE_SIMD_REP_FILL_IMPL_2(SEQAN_CREATE_SIMD_REP_IMPL_##SIZE, data, chrPos)
-
-#define SEQAN_CREATE_SIMD_REP_IMPL(SIZE)                                                \
-template <typename TSimdVecs, typename TStrings>                                        \
-inline void _createSimdRepImpl(TSimdVecs & simdStr,                                     \
-                               TStrings const & strings,                                \
-                               VectorLength_<SIZE> const & /*size*/)                    \
-{                                                                                       \
-    auto itB = begin(simdStr, Standard());                                              \
-    auto itE = end(simdStr, Standard());                                                \
-    for (auto it = itB; it != itE; ++it)                                                \
-        fillVector(*it, SEQAN_CREATE_SIMD_REP_FILL_IMPL(strings, it - itB, SIZE));      \
+template <typename TSimdVecs,
+          typename TStrings,
+          size_t ...I>
+inline void
+_createSimdRepImpl(TSimdVecs & vecs,
+                   TStrings const & strs,
+                   std::index_sequence<I...> const & /*unsued*/)
+{
+    for (size_t pos = 0; pos < length(vecs); ++pos)
+        fillVector(vecs[pos], strs[I][pos]...);
 }
 
-SEQAN_CREATE_SIMD_REP_IMPL(2)
-SEQAN_CREATE_SIMD_REP_IMPL(4)
-SEQAN_CREATE_SIMD_REP_IMPL(8)
-SEQAN_CREATE_SIMD_REP_IMPL(16)
-SEQAN_CREATE_SIMD_REP_IMPL(32)
-
-template <typename TSimdVecs, typename TStrings>
-inline void _createSimdRepImpl(TSimdVecs & simdStr,
-                               TStrings const & strings)
+template <typename TSimdVecs,
+          typename TStrings>
+inline void
+_createSimdRepImpl(TSimdVecs & simdStr,
+                   TStrings const & strings)
 {
-    _createSimdRepImpl(simdStr, strings, VectorLength_<LENGTH<typename Value<TSimdVecs>::Type>::VALUE>());
+    using TSimdVec = typename Value<TSimdVecs>::Type;
+    constexpr auto length = LENGTH<TSimdVec>::VALUE;
+    _createSimdRepImpl(simdStr, strings, std::make_index_sequence<length>());
 }
 
 // Actually precompute value if scoring scheme is score matrix and simd version.
@@ -187,46 +177,47 @@ _prepareAndRunSimdAlignment(TResult & results,
     SEQAN_ASSERT_EQ(length(seqH), length(seqV));
     SEQAN_ASSERT_EQ(static_cast<decltype(length(seqH))>(LENGTH<TResult>::VALUE), length(seqH));
 
+    using TSimdValueType = typename Value<TResult>::Type;
+
     using TPadStringH = ModifiedString<typename Value<TSequencesH const>::Type, ModPadding>;
     using TPadStringV = ModifiedString<typename Value<TSequencesV const>::Type, ModPadding>;
 
     String<TResult, Alloc<OverAligned> > stringSimdH;
     String<TResult, Alloc<OverAligned> > stringSimdV;
 
-    DPScoutState_<SimdAlignVariableLength<SimdAlignVariableLengthTraits<TResult, TSequencesH, TSequencesV> > > state;
+    using TDPProfile = typename SetupAlignmentProfile_<TAlgo, TFreeEndGaps, TGapModel, TTraceback>::Type;
+    DPScoutState_<SimdAlignVariableLength<SimdAlignVariableLengthTraits<TResult, TSequencesH, TSequencesV, TDPProfile> > > state;
 
     String<size_t> lengthsH;
     String<size_t> lengthsV;
 
-    resize(lengthsH, length(seqH));
-    resize(lengthsV, length(seqV));
-    resize(state.endsH, length(seqH));
-    resize(state.endsV, length(seqV));
+    resize(lengthsH, length(seqH), Exact{});
+    resize(lengthsV, length(seqV), Exact{});
 
     for (unsigned i = 0; i < length(seqH); ++i)
     {
-        lengthsH[i] = length(seqH[i]) - 1;
-        lengthsV[i] = length(seqV[i]) - 1;
-        state.endsH[i] = i;
-        state.endsV[i] = i;
+        lengthsH[i] = length(seqH[i]);
+        lengthsV[i] = length(seqV[i]);
     }
 
-    setHost(state.sortedEndsH, lengthsH);
-    setHost(state.sortedEndsV, lengthsV);
-    setCargo(state.sortedEndsH, state.endsH);
-    setCargo(state.sortedEndsV, state.endsV);
-
+    // Sort and remove unique elements from length vectors.
     auto maxLengthLambda = [](auto& lengthLhs, auto& lengthRhs) { return lengthLhs < lengthRhs; };
-    sort(state.sortedEndsH, maxLengthLambda, Serial());
-    sort(state.sortedEndsV, maxLengthLambda, Serial());
+    std::sort(begin(lengthsH, Standard{}), end(lengthsH, Standard{}), maxLengthLambda);
+    std::sort(begin(lengthsV, Standard{}), end(lengthsV, Standard{}), maxLengthLambda);
+
+    erase(lengthsH,
+          std::unique(begin(lengthsH, Standard{}), end(lengthsH, Standard{})) - begin(lengthsH, Standard{}),
+          length(lengthsH));
+    erase(lengthsV,
+          std::unique(begin(lengthsV, Standard{}), end(lengthsV, Standard{})) - begin(lengthsV, Standard{}),
+          length(lengthsV));
 
-    size_t maxH = back(state.sortedEndsH) + 1;
-    size_t maxV = back(state.sortedEndsV) + 1;
+    // Initialize iterator to the lengths vectors.
+    state.nextEndsH = begin(lengthsH, Rooted{});
+    state.nextEndsV = begin(lengthsV, Rooted{});
 
-    // and we have to prepare the bit masks of the DPScoutState
-    resize(state.masks,  maxV, createVector<TResult>(0));
-    resize(state.masksV, maxV, createVector<TResult>(0));
-    resize(state.masksH, maxH, createVector<TResult>(0));
+    size_t maxH = back(lengthsH);
+    size_t maxV = back(lengthsV);
 
     // Create Stringset with padded strings.
     StringSet<TPadStringH> paddedH;
@@ -241,9 +232,9 @@ _prepareAndRunSimdAlignment(TResult & results,
         expand(paddedH[i], maxH);
         expand(paddedV[i], maxV);
 
-        // mark the original end position of the alignment in the masks (with -1, all bits set)
-        assignValue(state.masksH[lengthsH[i]], i, -1);
-        assignValue(state.masksV[lengthsV[i]], i, -1);
+        // Store the end points as vector in both dimensions.
+        assignValue(state.endPosVecH, i, static_cast<TSimdValueType>(length(seqH[i])));
+        assignValue(state.endPosVecV, i, static_cast<TSimdValueType>(length(seqV[i])));
     }
 
     // now create SIMD representation
@@ -252,11 +243,6 @@ _prepareAndRunSimdAlignment(TResult & results,
     _createSimdRepImpl(stringSimdH, paddedH);
     _createSimdRepImpl(stringSimdV, paddedV);
 
-    state.dimV = length(stringSimdV);
-    state.isLocalAlignment = IsLocalAlignment_<TAlgo>::VALUE;
-    state.right = IsFreeEndGap_<TFreeEndGaps, DPLastColumn>::VALUE;
-    state.bottom = IsFreeEndGap_<TFreeEndGaps, DPLastRow>::VALUE;
-
     results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel());
 }
 
@@ -286,7 +272,8 @@ _prepareAndRunSimdAlignment(TResult & results,
                                          (length(std::get<1>(param)) == seqLengthV);
                                      });
     if(allSameLength)
-        _prepareAndRunSimdAlignment(results, traces, seqH, seqV, scoringScheme, alignConfig, TGapModel(), SimdAlignEqualLength());
+        _prepareAndRunSimdAlignment(results, traces, seqH, seqV, scoringScheme, alignConfig, TGapModel(),
+                                    SimdAlignEqualLength());
     else
         _prepareAndRunSimdAlignment(results, traces, seqH, seqV, scoringScheme, alignConfig, TGapModel(),
                                     SimdAlignVariableLength<Nothing>());
@@ -514,4 +501,3 @@ _alignWrapperSimd(StringSet<Gaps<TSequenceH, TGapsSpecH>, TSetSpecH> & gapSeqSet
 
 }  // namespace seqan
 #endif  // #ifndef INCLUDE_SEQAN_ALIGN_DP_ALIGN_SIMD_HELPER_H_
-
diff --git a/include/seqan/align/dp_meta_info.h b/include/seqan/align/dp_meta_info.h
index dab1bdc..3fd7c72 100644
--- a/include/seqan/align/dp_meta_info.h
+++ b/include/seqan/align/dp_meta_info.h
@@ -451,7 +451,7 @@ struct TrackingEnabled_<TDPMetaColumn, LastCell>:
 template <typename TAlgo, typename TColumnDescriptor>
 struct LastColumnEnabled_
 {
-    typedef typename IsSameType<typename TColumnDescriptor::TColumnProperty, DPLastColumn>::Type Type;
+    typedef typename IsSameType<typename TColumnDescriptor::TColumnProperty, DPFinalColumn>::Type Type;
 };
 
 template <typename TAlgo, typename TGapSpec, typename TTraceSpec, typename TColumnDescriptor>
diff --git a/include/seqan/align/dp_profile.h b/include/seqan/align/dp_profile.h
index f57e161..5f5c5f7 100644
--- a/include/seqan/align/dp_profile.h
+++ b/include/seqan/align/dp_profile.h
@@ -119,6 +119,7 @@ struct InitSimdTrace_;
 #define SEQAN_SIMD_INIT_FILL_VALUE_16_ SEQAN_SIMD_INIT_FILL_VALUE_8_, SEQAN_SIMD_INIT_FILL_VALUE_8_
 #define SEQAN_SIMD_INIT_FILL_VALUE_32_ SEQAN_SIMD_INIT_FILL_VALUE_16_, SEQAN_SIMD_INIT_FILL_VALUE_16_
 
+#ifdef COMPILER_MSVC
 #define SEQAN_SIMD_TRACE_SETUP_2_(SIZE, ...)                                                        \
 template <typename TVector, __uint8 FILL_VALUE>                                                     \
 struct InitSimdTrace_<TVector, FILL_VALUE, SIZE>                                                    \
@@ -128,6 +129,17 @@ struct InitSimdTrace_<TVector, FILL_VALUE, SIZE>
                                                                                                     \
 template <typename TVector, __uint8 FILL_VALUE>                                                     \
 const TVector InitSimdTrace_<TVector, FILL_VALUE, SIZE>::VALUE = TVector{__VA_ARGS__};
+#else // COMPILER_MSVC
+#define SEQAN_SIMD_TRACE_SETUP_2_(SIZE, ...)                                                        \
+template <typename TVector, __uint8 FILL_VALUE>                                                     \
+struct InitSimdTrace_<TVector, FILL_VALUE, SIZE>                                                    \
+{                                                                                                   \
+    static const TVector VALUE;                                                                     \
+};                                                                                                  \
+                                                                                                    \
+template <typename TVector, __uint8 FILL_VALUE>                                                     \
+const TVector InitSimdTrace_<TVector, FILL_VALUE, SIZE>::VALUE{__VA_ARGS__};
+#endif // COMPILER_MSVC
 
 #define SEQAN_SIMD_TRACE_SETUP_1_(SIZE, MACRO) SEQAN_SIMD_TRACE_SETUP_2_(SIZE, MACRO)
 #define SEQAN_SIMD_TRACE_SETUP_(SIZE) SEQAN_SIMD_TRACE_SETUP_1_(SIZE, SEQAN_SIMD_INIT_FILL_VALUE_ ## SIZE ## _)
diff --git a/include/seqan/align/dp_scout_simd.h b/include/seqan/align/dp_scout_simd.h
index 92095d2..a7615a8 100644
--- a/include/seqan/align/dp_scout_simd.h
+++ b/include/seqan/align/dp_scout_simd.h
@@ -72,70 +72,16 @@ public:
     using TSizeH = typename Size<typename TTraits::TSeqH>::Type;
     using TSizeV = typename Size<typename TTraits::TSeqV>::Type;
 
-    String<typename TTraits::TSimdVector, Alloc<OverAligned> > masksH;
-    String<typename TTraits::TSimdVector, Alloc<OverAligned> > masksV;
-    String<typename TTraits::TSimdVector, Alloc<OverAligned> > masks;
+    using TIterator = typename Iterator<String<size_t>, Rooted>::Type;
 
-    String<size_t> endsH;
-    String<size_t> endsV;
-    ModifiedString<String<size_t>, ModPos<String<size_t> > > sortedEndsH;
-    ModifiedString<String<size_t>, ModPos<String<size_t> > > sortedEndsV;
+    typename TTraits::TSimdVector endPosVecH;
+    typename TTraits::TSimdVector endPosVecV;
 
-    decltype(begin(sortedEndsH, Standard())) nextEndsH;
-    decltype(begin(sortedEndsV, Standard())) nextEndsV;
-
-    size_t dimV;
     size_t posH;
     size_t posV;
-    bool right;
-    bool bottom;
-    bool isLocalAlignment;
-
-    // ----------------------------------------------------------------------------
-    // Function DPScout_#updateMasksRight()
-    // ----------------------------------------------------------------------------
-
-    inline void updateMasksRight()
-    {
-        for(size_t pos = dimV - 2; pos != MaxValue<size_t>::VALUE; --pos)
-            masks[pos] |= masks[pos + 1];
-    }
-
-    // ----------------------------------------------------------------------------
-    // Function DPScout_#updateMasksBottom()
-    // ----------------------------------------------------------------------------
-
-    inline void updateMasksBottom()
-    {
-        for (auto posIt  = begin(sortedEndsV, Standard()); posIt != end(sortedEndsV, Standard()); ++posIt)
-            for (auto it = nextEndsH; it != end(sortedEndsH, Standard()); ++it)
-            {
-                masks[*posIt] |= (masksH[*it] & masksV[*posIt]);
-            }
-    }
-
-    // ----------------------------------------------------------------------------
-    // Function DPScout_#updateMasks()
-    // ----------------------------------------------------------------------------
-
-    inline void updateMasks()
-    {
-        for(size_t pos = 0; pos < dimV; ++pos)
-            masks[pos] = masksH[posH] & masksV[pos];
-        //for local alignments the BOTTOM parameter must be checked first
-        if(isLocalAlignment)
-        {
-            updateMasksBottom();
-            updateMasksRight();
-        }
-        else
-        {
-            if(right && posH == *nextEndsH)
-                updateMasksRight();
-            if(bottom)
-                updateMasksBottom();
-        }
-    }
+
+    TIterator nextEndsH;
+    TIterator nextEndsV;
 };
 
 // ----------------------------------------------------------------------------
@@ -233,7 +179,16 @@ _updateHostPositions(DPScout_<TDPCell, TScoutSpec> & dpScout,
                      SimdVector<int32_t>::Type positionNavigator)
 {
 // TODO(rrahn): Refactor!
-#if defined(__AVX2__)
+#if SEQAN_UMESIMD_ENABLED
+    using TSimdHalfVec = typename UME::SIMD::SIMDTraits<TSimdVec>::HALF_LEN_VEC_T;
+    TSimdHalfVec cmpLow, cmpHigh;
+    cmp.unpack(cmpLow, cmpHigh);
+
+    dpScout._maxHostLow = blend(dpScout._maxHostLow, positionNavigator,
+                                static_cast<SimdVector<int32_t>::Type>(cmpLow));
+    dpScout._maxHostHigh = blend(dpScout._maxHostHigh, positionNavigator,
+                                 static_cast<SimdVector<int32_t>::Type>(cmpHigh));
+#elif defined(__AVX2__)
     dpScout._maxHostLow = blend(dpScout._maxHostLow, positionNavigator,
                                 _mm256_cvtepi16_epi32(_mm256_castsi256_si128(reinterpret_cast<__m256i&>(cmp))));
     dpScout._maxHostHigh = blend(dpScout._maxHostHigh, positionNavigator,
@@ -247,7 +202,7 @@ _updateHostPositions(DPScout_<TDPCell, TScoutSpec> & dpScout,
 }
 
 // ----------------------------------------------------------------------------
-// Function _scoutBestScore()
+// Function _scoutBestScore()                            [SimdAlignEqualLength]
 // ----------------------------------------------------------------------------
 
 template <typename TDPCell, typename TTraceMatrixNavigator, typename TIsLastColumn, typename TIsLastRow>
@@ -263,6 +218,172 @@ _scoutBestScore(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignEqualLength> > & d
     _updateHostPositions(dpScout, cmp, createVector<SimdVector<int32_t>::Type>(position(navigator)));
 }
 
+// ----------------------------------------------------------------------------
+// Function _getCompareMask()
+// ----------------------------------------------------------------------------
+
+// Helper functions to resolve the correct tracking of cells for different
+// alignment modes.
+
+// Standard global alignment.
+template <typename TDPCell, typename TTraits,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & dpScout,
+                            True const & /*lastCol*/,
+                            True const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, False, False>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return ((dpScout.state->endPosVecH) == createVector<TSimdVec>(dpScout.state->posH)) &
+           ((dpScout.state->endPosVecV) == createVector<TSimdVec>(dpScout.state->posV));
+}
+
+template <typename TDPCell, typename TTraits,
+          typename TIsLastColumn,
+          typename TIsLastRow,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & /*dpScout*/,
+                            TIsLastColumn const & /*lastCol*/,
+                            TIsLastRow const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, False, False>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return createVector<TSimdVec>(0);
+}
+
+// Tracking the last row is enabled
+template <typename TDPCell, typename TTraits,
+          typename TIsLastColumn,
+          typename TIsLastRow,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & dpScout,
+                            TIsLastColumn const & /*lastCol*/,
+                            TIsLastRow const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, True, False>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return (createVector<TSimdVec>(dpScout.state->posH) <= (dpScout.state->endPosVecH)) &
+           (createVector<TSimdVec>(dpScout.state->posV) == (dpScout.state->endPosVecV));
+}
+
+template <typename TDPCell, typename TTraits,
+          typename TIsLastColumn,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & /*dpScout*/,
+                            TIsLastColumn const & /*lastCol*/,
+                            False const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, True, False>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return createVector<TSimdVec>(0);
+}
+
+// Tracking if the last column is enabled
+template <typename TDPCell, typename TTraits,
+          typename TIsLastColumn,
+          typename TIsLastRow,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & dpScout,
+                            TIsLastColumn const & /*lastCol*/,
+                            TIsLastRow const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, False, True>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return (createVector<TSimdVec>(dpScout.state->posH) == (dpScout.state->endPosVecH)) &
+           (createVector<TSimdVec>(dpScout.state->posV) <= (dpScout.state->endPosVecV));
+}
+
+template <typename TDPCell, typename TTraits,
+          typename TIsLastRow,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & /*dpScout*/,
+                            False const & /*lastCol*/,
+                            TIsLastRow const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, False, True>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return createVector<TSimdVec>(0);
+}
+
+// Tracking if the last column and last row is enabled
+template <typename TDPCell, typename TTraits,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & dpScout,
+                            True const & /*lastCol*/,
+                            True const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, True, True>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return ((createVector<TSimdVec>(dpScout.state->posH) == (dpScout.state->endPosVecH)) &
+            (createVector<TSimdVec>(dpScout.state->posV) <= (dpScout.state->endPosVecV))) |
+           ((createVector<TSimdVec>(dpScout.state->posH) <= (dpScout.state->endPosVecH)) &
+            (createVector<TSimdVec>(dpScout.state->posV) == (dpScout.state->endPosVecV)));
+}
+
+template <typename TDPCell, typename TTraits,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & dpScout,
+                            False const & /*lastCol*/,
+                            True const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, True, True>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return (createVector<TSimdVec>(dpScout.state->posH) <= (dpScout.state->endPosVecH)) &
+           (createVector<TSimdVec>(dpScout.state->posV) == (dpScout.state->endPosVecV));
+}
+
+template <typename TDPCell, typename TTraits,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & dpScout,
+                            True const & /*lastCol*/,
+                            False const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, True, True>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return (createVector<TSimdVec>(dpScout.state->posH) == (dpScout.state->endPosVecH)) &
+           (createVector<TSimdVec>(dpScout.state->posV) <= (dpScout.state->endPosVecV));
+}
+
+template <typename TDPCell, typename TTraits,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & /*dpScout*/,
+                            False const & /*lastCol*/,
+                            False const & /*lastRow*/,
+                            DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, True, True>>,
+                                       TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return createVector<TSimdVec>(0);
+}
+
+// If local alignment.
+template <typename TDPCell, typename TTraits,
+          typename TIsLastColumn,
+          typename TIsLastRow,
+          typename TAlgoSpec, typename TGapModel, typename TTraceConfig>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & dpScout,
+                            TIsLastColumn const & /*lastCol*/,
+                            TIsLastRow const & /*lastRow*/,
+                            DPProfile_<LocalAlignment_<TAlgoSpec>, TGapModel, TTraceConfig> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return (createVector<TSimdVec>(dpScout.state->posH) <= (dpScout.state->endPosVecH)) &
+           (createVector<TSimdVec>(dpScout.state->posV) <= (dpScout.state->endPosVecV));
+}
+
+// ----------------------------------------------------------------------------
+// Function _scoutBestScore()                         [SimdAlignVariableLength]
+// ----------------------------------------------------------------------------
+
 template <typename TDPCell, typename TTraits,
           typename TTraceMatrixNavigator,
           typename TIsLastColumn,
@@ -274,10 +395,10 @@ _scoutBestScore(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTr
                 TIsLastColumn const & /**/,
                 TIsLastRow const & /**/)
 {
-    auto cmp = cmpGt(_scoreOfCell(activeCell), _scoreOfCell(dpScout._maxScore));
-    cmp &= dpScout.state->masks[dpScout.state->posV];
-    _copySimdCell(dpScout, activeCell, cmp);
-    _updateHostPositions(dpScout, cmp, createVector<SimdVector<int32_t>::Type>(position(navigator)));
+    auto mask = cmpGt(_scoreOfCell(activeCell), _scoreOfCell(dpScout._maxScore)) &
+                _getCompareMask(dpScout, TIsLastColumn{}, TIsLastRow{}, typename TTraits::TDPProfile{});
+    _copySimdCell(dpScout, activeCell, mask);
+    _updateHostPositions(dpScout, mask, createVector<SimdVector<int32_t>::Type>(position(navigator)));
 }
 
 // ----------------------------------------------------------------------------
@@ -313,7 +434,7 @@ template <typename TDPCell, typename TTraits>
 inline void
 _preInitScoutHorizontal(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > & scout)
 {
-    scout.state->nextEndsH = begin(scout.state->sortedEndsH, Standard());
+    goBegin(scout.state->nextEndsH);
     scout.state->posH = 0;
 }
 
@@ -325,8 +446,8 @@ template <typename TDPCell, typename TTraits>
 inline void
 _preInitScoutVertical(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > & scout)
 {
-    scout.state->updateMasks();
-    scout.state->nextEndsV = begin(scout.state->sortedEndsV, Standard());
+    // scout.state->updateMasks();
+    goBegin(scout.state->nextEndsV);
     scout.state->posV = 0;
 }
 
@@ -339,7 +460,7 @@ inline bool
 _reachedHorizontalEndPoint(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > & scout,
                            TIter const & hIt)
 {
-    return *(scout.state->nextEndsH) == position(hIt);
+    return *(scout.state->nextEndsH) == position(hIt) + 1;
 }
 
 // ----------------------------------------------------------------------------
@@ -351,7 +472,7 @@ inline bool
 _reachedVerticalEndPoint(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > & scout,
                          TIter const & vIt)
 {
-    return *(scout.state->nextEndsV) == position(vIt);
+    return *(scout.state->nextEndsV) == position(vIt) + 1;
 }
 
 // ----------------------------------------------------------------------------
@@ -362,12 +483,7 @@ template <typename TDPCell, typename TTraits>
 inline void
 _nextHorizontalEndPos(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > & scout)
 {
-    auto oldLength = *scout.state->nextEndsH;
-    while (scout.state->nextEndsH != end(scout.state->sortedEndsH, Standard()) &&
-           *scout.state->nextEndsH == oldLength)
-    {
-        ++scout.state->nextEndsH;
-    }
+    ++scout.state->nextEndsH;
 }
 
 // ----------------------------------------------------------------------------
@@ -378,12 +494,7 @@ template <typename TDPCell, typename TTraits>
 inline void
 _nextVerticalEndPos(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > & scout)
 {
-    auto oldLength = *scout.state->nextEndsV;
-    while (scout.state->nextEndsV != end(scout.state->sortedEndsV, Standard()) &&
-           *scout.state->nextEndsV == oldLength)
-    {
-        ++scout.state->nextEndsV;
-    }
+    ++scout.state->nextEndsV;
 }
 
 // ----------------------------------------------------------------------------
@@ -425,7 +536,7 @@ inline auto
 _hostLengthH(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & scout,
              TSeqH const & /*seqH*/)
 {
-    return host(scout.state->sortedEndsH)[scout._simdLane] + 1;
+    return (scout.state->endPosVecH)[scout._simdLane];
 }
 
 // ----------------------------------------------------------------------------
@@ -445,10 +556,9 @@ inline auto
 _hostLengthV(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & scout,
              TSeqV const & /*seqV*/)
 {
-    return host(scout.state->sortedEndsV)[scout._simdLane] + 1;
+    return (scout.state->endPosVecV)[scout._simdLane];
 }
 
 }  // namespace seqan
 
 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_SIMD_DP_SCOUT_SIMD_H_
-
diff --git a/include/seqan/align/dp_traceback_impl.h b/include/seqan/align/dp_traceback_impl.h
index a2439f9..0e7cc72 100644
--- a/include/seqan/align/dp_traceback_impl.h
+++ b/include/seqan/align/dp_traceback_impl.h
@@ -515,8 +515,8 @@ _computeTraceback(TTarget & target,
     // Set the navigator to the position where the maximum was found.
     _setToPosition(matrixNavigator, maxHostPosition);
 
-    SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::HORIZONTAL), seqHSize);
-    SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::VERTICAL), seqVSize);
+    SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::HORIZONTAL), static_cast<TSize>(seqHSize));
+    SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::VERTICAL), static_cast<TSize>(seqVSize));
 
     TTraceValue traceValue = scalarValue(matrixNavigator);
     TTraceValue lastTraceValue = _retrieveInitialTraceDirection(traceValue, dpProfile);
@@ -527,10 +527,10 @@ _computeTraceback(TTarget & target,
 
     if (TraceTail_<TAlgorithm>::VALUE)
     {
-        if (tracebackCoordinator._currRow != seqVSize)
+        if (tracebackCoordinator._currRow != static_cast<TSize>(seqVSize))
             _recordSegment(target, seqHSize, tracebackCoordinator._currRow, seqVSize - tracebackCoordinator._currRow,
                            +TraceBitMap_<>::VERTICAL);
-        if (tracebackCoordinator._currColumn != seqHSize)
+        if (tracebackCoordinator._currColumn != static_cast<TSize>(seqHSize))
             _recordSegment(target, tracebackCoordinator._currColumn, tracebackCoordinator._currRow, seqHSize -
                            tracebackCoordinator._currColumn, +TraceBitMap_<>::HORIZONTAL);
     }
diff --git a/include/seqan/arg_parse/arg_parse_version_check.h b/include/seqan/arg_parse/arg_parse_version_check.h
index bb10cc8..18865f1 100644
--- a/include/seqan/arg_parse/arg_parse_version_check.h
+++ b/include/seqan/arg_parse/arg_parse_version_check.h
@@ -68,18 +68,18 @@ struct VersionControlTags_
     static constexpr char const * const UNREGISTERED_APP   = "UNREGISTERED_APP";
 
     static constexpr char const * const MESSAGE_SEQAN_UPDATE =
-        "[SEQAN INFO] :: There is a newer SeqAn version available!\n"
+        "[SEQAN INFO] :: A new SeqAn version is available online.\n"
         "[SEQAN INFO] :: Please visit www.seqan.de for an update or inform the developer of this app.\n"
-        "[SEQAN INFO] :: If you don't want to recieve this message again set --version-check OFF\n\n";
+        "[SEQAN INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n";
     static constexpr char const * const MESSAGE_APP_UPDATE =
-        "[APP INFO] :: There is a newer version of this application available.\n"
-        "[APP INFO] :: If this app is developed by SeqAn, visit www.seqan.de for updates.\n"
-        "[APP INFO] :: If you don't want to recieve this message again set --version_check OFF\n\n";
+        "[APP INFO] :: A new version of this application is now available.\n"
+        "[APP INFO] :: Visit www.seqan.de for updates of official SeqAn applications.\n"
+        "[APP INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n";
     static constexpr char const * const MESSAGE_UNREGISTERED_APP =
         "[SEQAN INFO] :: Thank you for using SeqAn!\n"
-        "[SEQAN INFO] :: You might want to regsiter you app for support and version check features?\n"
-        "[SEQAN INFO] :: Just send us an email to seqan at team.fu-berlin.de with your app name and version number.\n"
-        "[SEQAN INFO] :: If you don't want to recieve this message anymore set --version_check OFF\n\n";
+        "[SEQAN INFO] :: Do you wish to register your app for update notifications?\n"
+        "[SEQAN INFO] :: Just send an email to support at seqan.de with your app name and version number.\n"
+        "[SEQAN INFO] :: If you don't wish to receive further notifications, set --version-check OFF.\n\n";
     static constexpr char const * const MESSAGE_REGISTERED_APP_UPDATE =
         "[APP INFO] :: We noticed the app version you use is newer than the one registered with us.\n"
         "[APP INFO] :: Please send us an email with the new version so we can correct it (support at seqan.de)\n\n";
diff --git a/include/seqan/bam_io/bam_alignment_record.h b/include/seqan/bam_io/bam_alignment_record.h
index 4e694d5..209e08d 100644
--- a/include/seqan/bam_io/bam_alignment_record.h
+++ b/include/seqan/bam_io/bam_alignment_record.h
@@ -117,12 +117,12 @@ struct BamTypeChar
     {
         VALUE =
             (IsSameType<TValue, char>::VALUE)?              'A':
-            (IsSameType<TValue, signed char>::VALUE)?       'c':
-            (IsSameType<TValue, unsigned char>::VALUE)?     'C':
-            (IsSameType<TValue, short>::VALUE)?             's':
-            (IsSameType<TValue, unsigned short>::VALUE)?    'S':
-            (IsSameType<TValue, int>::VALUE)?               'i':
-            (IsSameType<TValue, unsigned int>::VALUE)?      'I':
+            (IsSameType<TValue, int8_t>::VALUE)?            'c':
+            (IsSameType<TValue, uint8_t>::VALUE)?           'C':
+            (IsSameType<TValue, int16_t>::VALUE)?           's':
+            (IsSameType<TValue, uint16_t>::VALUE)?          'S':
+            (IsSameType<TValue, int32_t>::VALUE)?           'i':
+            (IsSameType<TValue, uint32_t>::VALUE)?          'I':
             (IsSameType<TValue, float>::VALUE)?             'f':
 //          (IsSameType<TValue, double>::VALUE)?            'd':
             (IsSequence<TValue>::VALUE)?                    'Z':
@@ -131,14 +131,14 @@ struct BamTypeChar
 };
 
 // List of primitive BAM types (ordered by expected usage frequency)
-typedef TagList<int,
-        TagList<unsigned int,
+typedef TagList<int32_t,
+        TagList<uint32_t,
         TagList<float,
-        TagList<short,
-        TagList<unsigned short,
+        TagList<int16_t,
+        TagList<uint16_t,
         TagList<char,
-        TagList<unsigned char,
-        TagList<signed char
+        TagList<uint8_t,
+        TagList<int8_t
 //      TagList<double
         > > > > > > > > BamTagTypes;
 
@@ -607,6 +607,31 @@ getAlignmentLengthInRef(BamAlignmentRecord const & record)
     return l;
 }
 
+// ----------------------------------------------------------------------------
+// Function appendRawPod()
+// ----------------------------------------------------------------------------
+
+// This function is guarded so that we save the copy on little endian systems
+#if SEQAN_BIG_ENDIAN
+template <typename TTarget>
+inline void
+appendRawPod(TTarget & target, BamAlignmentRecordCore r)
+{
+    ensure_little_endian(r.rID);
+    ensure_little_endian(r.beginPos);
+    // _l_qname unchanged because 8bit
+    // mapQ unchanged because 8bit
+    r.bin       = htole16(r.bin);
+    r._n_cigar  = htole16(r._n_cigar);
+    r.flag      = htole16(r.flag);
+    ensure_little_endian(r._l_qseq);
+    ensure_little_endian(r.rNextId);
+    ensure_little_endian(r.pNext);
+    ensure_little_endian(r.tLen);
+    appendRawPodImpl(target, r);
+}
+#endif
+
 }  // namespace seqan
 
 #endif  // #ifndef INCLUDE_SEQAN_BAM_IO_BAM_RECORD_H_
diff --git a/include/seqan/bam_io/bam_index_bai.h b/include/seqan/bam_io/bam_index_bai.h
index db5ed68..da7ea47 100644
--- a/include/seqan/bam_io/bam_index_bai.h
+++ b/include/seqan/bam_io/bam_index_bai.h
@@ -298,10 +298,10 @@ jumpToRegion(FormattedFile<Bam, Input, TSpec> & bamFile,
         readRecord(record, bamFile);
 
         // std::cerr << "record.beginPos == " << record.beginPos << "\n";
-        // int32_t endPos = record.beginPos + getAlignmentLengthInRef(record);
+         int32_t endPos = record.beginPos + getAlignmentLengthInRef(record);
         if (record.rID != refId)
             continue;  // Wrong contig.
-        if (!hasAlignments || record.beginPos <= pos)
+        if (!hasAlignments && record.beginPos <= posEnd && pos <= endPos)
         {
             // Found a valid alignment.
             hasAlignments = true;
diff --git a/include/seqan/bam_io/bam_sam_conversion.h b/include/seqan/bam_io/bam_sam_conversion.h
index 4cec8de..f6e707b 100644
--- a/include/seqan/bam_io/bam_sam_conversion.h
+++ b/include/seqan/bam_io/bam_sam_conversion.h
@@ -128,7 +128,7 @@ void _appendTagsSamToBamOneTag(TTarget & target, TForwardIter & iter, CharString
                     ++nEntries;
 
             // Write out array length.
-            appendRawPod(target, (uint32_t)nEntries);
+            appendRawPod(target, nEntries);
 
             // Write out array values.
             size_t startPos = 1;
diff --git a/include/seqan/bam_io/read_bam.h b/include/seqan/bam_io/read_bam.h
index 71059c8..52dc510 100644
--- a/include/seqan/bam_io/read_bam.h
+++ b/include/seqan/bam_io/read_bam.h
@@ -236,7 +236,7 @@ readRecord(BamAlignmentRecord & record,
     TCigarIter cigEnd = end(record.cigar, Standard());
     for (TCigarIter cig = begin(record.cigar, Standard()); cig != cigEnd; ++cig)
     {
-        unsigned opAndCnt;
+        uint32_t opAndCnt;
         readRawPod(opAndCnt, it);
         SEQAN_ASSERT_LEQ(opAndCnt & 15, 8u);
         cig->operation = CIGAR_MAPPING[opAndCnt & 15];
diff --git a/include/seqan/basic.h b/include/seqan/basic.h
index 0cf12db..03187a6 100644
--- a/include/seqan/basic.h
+++ b/include/seqan/basic.h
@@ -106,7 +106,4 @@
 // Basic device metafunctions.
 #include <seqan/basic/basic_device.h>
 
-// Basic SIMD vector implementation using intrinsics.
-#include <seqan/basic/basic_simd_vector.h>
-
 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_H_
diff --git a/include/seqan/basic/alphabet_residue.h b/include/seqan/basic/alphabet_residue.h
index fae9710..3c57c47 100644
--- a/include/seqan/basic/alphabet_residue.h
+++ b/include/seqan/basic/alphabet_residue.h
@@ -768,6 +768,17 @@ inline void assign(Rna & target, char c_source)
 }
 
 template <>
+struct CompareTypeImpl<Rna5, Iupac>
+{
+    typedef Rna5 Type;
+};
+
+inline void assign(Rna5 & target, Iupac const & source)
+{
+    target.value = TranslateTableIupacToDna5_<>::VALUE[source.value];
+}
+
+template <>
 struct CompareTypeImpl<Rna, Rna5>
 {
     typedef Rna Type;
diff --git a/include/seqan/basic/basic_simd_vector.h b/include/seqan/basic/basic_simd_vector.h
deleted file mode 100644
index 40f6e56..0000000
--- a/include/seqan/basic/basic_simd_vector.h
+++ /dev/null
@@ -1,1671 +0,0 @@
-// ==========================================================================
-//                 SeqAn - The Library for Sequence Analysis
-// ==========================================================================
-// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
-//       its contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-// DAMAGE.
-//
-// ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-//         René Rahn <rene.rahn at fu-berlin.de>
-//         Stefan Budach <stefan.budach at fu-berlin.de>
-// ==========================================================================
-// generic SIMD interface for SSE3 / AVX2
-// ==========================================================================
-
-#ifndef SEQAN_INCLUDE_SEQAN_BASIC_SIMD_VECTOR_H_
-#define SEQAN_INCLUDE_SEQAN_BASIC_SIMD_VECTOR_H_
-
-#include <utility>
-#include <tuple>
-
-// Currently only support the following compilers
-#if defined(COMPILER_GCC) || defined(COMPILER_CLANG) || defined(COMPILER_LINTEL)
-    // Define global macro to check if simd instructions are enabled.
-    #define SEQAN_SIMD_ENABLED
-
-    // Define maximal size of vector in byte.
-    #if defined(__AVX2__)
-        #define SEQAN_SIZEOF_MAX_VECTOR 32
-    #elif defined(__SSE4_1__) && defined(__SSE4_2__)
-        #define SEQAN_SSE4
-        #define SEQAN_SIZEOF_MAX_VECTOR 16
-    #else  // defined(__AVX2__)
-        #undef SEQAN_SIMD_ENABLED  // Disable simd if instruction set is not supported.
-    #endif  // defined(__AVX2__)
-#endif  // defined(COMPILER_GCC) || defined(COMPILER_CLANG) || defined(COMPILER_LINTEL)
-
-#ifdef SEQAN_SIMD_ENABLED  // Include header with intrinsics.
-    #include <x86intrin.h>
-#endif  // SEQAN_SIMD_ENABLED
-
-namespace seqan {
-
-#ifdef COMPILER_LINTEL
-#include <type_traits>
-#define SEQAN_VECTOR_CAST_(T, v) static_cast<typename std::decay<T>::type>(v)
-#define SEQAN_VECTOR_CAST_LVALUE_(T, v) static_cast<T>(v)
-#else
-#define SEQAN_VECTOR_CAST_(T, v) reinterpret_cast<T>(v)
-#define SEQAN_VECTOR_CAST_LVALUE_(T, v) reinterpret_cast<T>(v)
-#endif
-
-// ============================================================================
-// Forwards
-// ============================================================================
-
-// ============================================================================
-// Useful Macros
-// ============================================================================
-
-#define SEQAN_DEFINE_SIMD_VECTOR_GETVALUE_(TSimdVector)                                                 \
-template <typename TPosition>                                                                           \
-inline typename Value<TSimdVector>::Type                                                                \
-getValue(TSimdVector &vector, TPosition pos)                                                            \
-{                                                                                                       \
-/*                                                                                                      \
-    typedef typename Value<TSimdVector>::Type TValue;                                                   \
-    TValue val = (SEQAN_VECTOR_CAST_(TValue*, &vector))[pos];                                           \
-    return val;                                                                                         \
-*/                                                                                                      \
-    return vector[pos];                                                                                 \
-}
-
-#define SEQAN_DEFINE_SIMD_VECTOR_VALUE_(TSimdVector)                                                    \
-template <typename TPosition>                                                                           \
-inline typename Value<TSimdVector>::Type                                                                \
-value(TSimdVector &vector, TPosition pos)                                                               \
-{                                                                                                       \
-    return getValue(vector, pos);                                                                       \
-}
-
-#define SEQAN_DEFINE_SIMD_VECTOR_ASSIGNVALUE_(TSimdVector)                                              \
-template <typename TPosition, typename TValue2>                                                         \
-inline void                                                                                             \
-assignValue(TSimdVector &vector, TPosition pos, TValue2 value)                                          \
-{                                                                                                       \
-/*                                                                                                      \
-    typedef typename Value<TSimdVector>::Type TValue;                                                   \
-    (SEQAN_VECTOR_CAST_(TValue*, &vector))[pos] = value;                                                \
-*/                                                                                                      \
-    vector[pos] = value;                                                                                \
-}
-
-// define a concept and its models
-// they allow us to define generic vector functions
-SEQAN_CONCEPT(SimdVectorConcept, (T)) {};
-
-// Only include following code if simd instructions are enabled.
-#ifdef SEQAN_SIMD_ENABLED
-
-// ============================================================================
-// Tags, Classes, Enums
-// ============================================================================
-
-// a metafunction returning the biggest supported SIMD vector
-template <typename TValue, int LENGTH = SEQAN_SIZEOF_MAX_VECTOR / sizeof(TValue)>
-struct SimdVector;
-
-// internal struct to specialize for vector parameters
-// VEC_SIZE = Vector size := sizeof(vec)
-// LENGTH = number of elements := VEC_SIZE / sizeof(InnerValue<TVec>::Type)
-template <int VEC_SIZE, int LENGTH = 0>
-struct SimdParams_ {};
-
-template <int SCALE>
-struct ScaleParam_
-{};
-
-// internal struct to specialize for matrix parameters
-template <int ROWS, int COLS, int BITS_PER_VALUE>
-struct SimdMatrixParams_ {};
-
-#define SEQAN_DEFINE_SIMD_VECTOR_(TSimdVector, TValue, SIZEOF_VECTOR)                                           \
-        typedef TValue TSimdVector __attribute__ ((__vector_size__(SIZEOF_VECTOR)));                            \
-        template <> struct SimdVector<TValue, SIZEOF_VECTOR / sizeof(TValue)> {  typedef TSimdVector Type; };   \
-        template <> struct Value<TSimdVector>           { typedef TValue Type; };                               \
-        template <> struct Value<TSimdVector const>:  public Value<TSimdVector> {};                             \
-        template <> struct LENGTH<TSimdVector>          { enum { VALUE = SIZEOF_VECTOR / sizeof(TValue) }; };   \
-        template <> struct LENGTH<TSimdVector const>: public LENGTH<TSimdVector> {};                            \
-        SEQAN_DEFINE_SIMD_VECTOR_GETVALUE_(TSimdVector)                                                         \
-        SEQAN_DEFINE_SIMD_VECTOR_GETVALUE_(TSimdVector const)                                                   \
-        SEQAN_DEFINE_SIMD_VECTOR_VALUE_(TSimdVector)                                                            \
-        SEQAN_DEFINE_SIMD_VECTOR_VALUE_(TSimdVector const)                                                      \
-        SEQAN_DEFINE_SIMD_VECTOR_ASSIGNVALUE_(TSimdVector)                                                      \
-        template <>                                                                                             \
-        SEQAN_CONCEPT_IMPL((TSimdVector),       (SimdVectorConcept));                                           \
-        template <>                                                                                             \
-        SEQAN_CONCEPT_IMPL((TSimdVector const), (SimdVectorConcept));
-
-#ifdef __AVX2__
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector32Char,     char,           32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector32SChar,    signed char,    32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector32UChar,    unsigned char,  32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16Short,    short,          32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16UShort,   unsigned short, 32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8Int,       int,            32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8UInt,      unsigned int,   32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4Int64,     int64_t,        32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4UInt64,    uint64_t,       32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8Float,     float,          32)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4Double,    double,         32)
-#endif  // __AVX2__
-
-#ifdef SEQAN_SSE4
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8Char,      char,           8)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8SChar,     signed char,    8)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8UChar,     unsigned char,  8)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4Short,     short,          8)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4UShort,    unsigned short, 8)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2Int,       int,            8)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2UInt,      unsigned int,   8)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2Float,     float,          8)
-
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16Char,     char,           16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16SChar,    signed char,    16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16UChar,    unsigned char,  16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8Short,     short,          16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8UShort,    unsigned short, 16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4Int,       int,            16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4UInt,      unsigned int,   16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2Int64,     int64_t,        16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2UInt64,    uint64_t,       16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4Float,     float,          16)
-SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2Double,    double,         16)
-#endif  // SEQAN_SSE4
-
-// ============================================================================
-// Functions
-// ============================================================================
-
-// ============================================================================
-// AVX/AVX2 wrappers (256bit vectors)
-// ============================================================================
-
-#ifdef __AVX2__
-
-// --------------------------------------------------------------------------
-// _fillVector (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename ...TValue>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & x, std::index_sequence<0> const &, SimdParams_<32, 32>) { SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set1_epi8(std::get<0>(x)); }
-template <typename TSimdVector, typename ...TValue>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & x, std::index_sequence<0> const &, SimdParams_<32, 16>) { SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set1_epi16(std::get<0>(x)); }
-template <typename TSimdVector, typename ...TValue>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & x, std::index_sequence<0> const &, SimdParams_<32, 8>)  { SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set1_epi32(std::get<0>(x)); }
-template <typename TSimdVector, typename ...TValue>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & x, std::index_sequence<0> const &, SimdParams_<32, 4>)  { SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set1_epi64x(std::get<0>(x)); }
-template <typename TSimdVector>
-    inline void _fillVector(TSimdVector &vector, std::tuple<float> const & x,  std::index_sequence<0> const &, SimdParams_<32, 8>)  { SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set1_ps(std::get<0>(x)); }
-template <typename TSimdVector>
-inline void _fillVector(TSimdVector &vector, std::tuple<double> const & x, std::index_sequence<0> const &, SimdParams_<32, 4>)  { SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set1_pd(std::get<0>(x)); }
-
-template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & values, std::index_sequence<INDICES...> const &, SimdParams_<32, 32>)
-{
-    SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set_epi8(std::get<INDICES>(values)...);
-}
-
-template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & values, std::index_sequence<INDICES...> const &, SimdParams_<32, 16>)
-{
-    SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set_epi16(std::get<INDICES>(values)...);
-}
-template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & values, std::index_sequence<INDICES...> const &, SimdParams_<32, 8>)
-{
-    SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set_epi32(std::get<INDICES>(values)...);
-}
-
-template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & values, std::index_sequence<INDICES...> const &, SimdParams_<32, 4>)
-{
-    SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_set_epi64x(std::get<INDICES>(values)...);
-}
-
-// --------------------------------------------------------------------------
-// _clearVector (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, int L>
-inline void _clearVector(TSimdVector &vector, SimdParams_<32, L>) { SEQAN_VECTOR_CAST_LVALUE_(__m256i&, vector) = _mm256_setzero_si256(); }
-template <typename TSimdVector>
-inline void _clearVector(TSimdVector &vector, SimdParams_<32, 8>) { SEQAN_VECTOR_CAST_LVALUE_(__m256&, vector) = _mm256_setzero_ps(); }
-template <typename TSimdVector>
-inline void _clearVector(TSimdVector &vector, SimdParams_<32, 4>) { SEQAN_VECTOR_CAST_LVALUE_(__m256d&, vector) = _mm256_setzero_pd(); }
-
-// --------------------------------------------------------------------------
-// _createVector (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename TValue>
-inline TSimdVector _createVector(TValue x, SimdParams_<32, 32>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi8(x)); }
-template <typename TSimdVector, typename TValue>
-inline TSimdVector _createVector(TValue x, SimdParams_<32, 16>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi16(x)); }
-template <typename TSimdVector, typename TValue>
-inline TSimdVector _createVector(TValue x, SimdParams_<32, 8>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi32(x)); }
-template <typename TSimdVector, typename TValue>
-inline TSimdVector _createVector(TValue x, SimdParams_< 32, 4>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi64x(x)); }
-template <typename TSimdVector>
-inline TSimdVector _createVector(float x,  SimdParams_<32, 8>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_ps(x)); }
-template <typename TSimdVector>
-inline TSimdVector _createVector(double x, SimdParams_<32, 4>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_pd(x)); }
-
-// --------------------------------------------------------------------------
-// _cmpEq (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _cmpEq(TSimdVector &a, TSimdVector &b, SimdParams_<32, 32>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpeq_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                             SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpEq(TSimdVector &a, TSimdVector &b, SimdParams_<32, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpeq_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpEq(TSimdVector &a, TSimdVector &b, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpeq_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpEq(TSimdVector &a, TSimdVector &b, SimdParams_<32, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpeq_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _cmpGt (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _cmpGt(TSimdVector &a, TSimdVector &b, SimdParams_<32, 32>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpgt_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                             SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpGt(TSimdVector &a, TSimdVector &b, SimdParams_<32, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpgt_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpGt(TSimdVector &a, TSimdVector &b, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpgt_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpGt(TSimdVector &a, TSimdVector &b, SimdParams_<32, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpgt_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _bitwiseOr (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, int L>
-inline TSimdVector _bitwiseOr(TSimdVector &a, TSimdVector &b, SimdParams_<32, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_or_si256(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                           SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _bitwiseAnd (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, int L>
-inline TSimdVector _bitwiseAnd(TSimdVector &a, TSimdVector &b, SimdParams_<32, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_and_si256(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                            SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseAnd(TSimdVector &a, TSimdVector &b, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_and_ps(SEQAN_VECTOR_CAST_(const __m256&, a),
-                                                         SEQAN_VECTOR_CAST_(const __m256&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseAnd(TSimdVector &a, TSimdVector &b, SimdParams_<32, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_and_pd(SEQAN_VECTOR_CAST_(const __m256d&, a),
-                                                         SEQAN_VECTOR_CAST_(const __m256d&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _bitwiseAndNot (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, int L>
-inline TSimdVector _bitwiseAndNot(TSimdVector &a, TSimdVector &b, SimdParams_<32, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_andnot_si256(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _bitwiseNot (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseNot(TSimdVector &a, SimdParams_<32, 32>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_cmpeq_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_setzero_si256()));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseNot(TSimdVector &a, SimdParams_<32, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_cmpeq_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_setzero_si256()));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseNot(TSimdVector &a, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_cmpeq_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_setzero_si256()));
-
-}
-template <typename TSimdVector>
-inline TSimdVector _bitwiseNot(TSimdVector &a, SimdParams_<32, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_cmpeq_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_setzero_si256()));
-}
-
-// --------------------------------------------------------------------------
-// _divide (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _divide(TSimdVector &a, int b, SimdParams_<32, 32>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_div_epi8(a, _mm256_set1_epi8(b))); }
-
-template <typename TSimdVector>
-inline TSimdVector _divide(TSimdVector &a, int b, SimdParams_<32, 16>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_div_epi16(a, _mm256_set1_epi16(b))); }
-
-template <typename TSimdVector>
-inline TSimdVector _divide(TSimdVector &a, int b, SimdParams_<32, 8>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_div_epi32(a, _mm256_set1_epi32(b))); }
-
-template <typename TSimdVector>
-inline TSimdVector _divide(TSimdVector &a, int b, SimdParams_<32, 4>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_div_epi64(a, _mm256_set1_epi64x(b))); }
-
-// --------------------------------------------------------------------------
-// _add (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _add(TSimdVector &a, TSimdVector &b, SimdParams_<32, 32>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_add_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _add(TSimdVector &a, TSimdVector &b, SimdParams_<32, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_add_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _add(TSimdVector &a, TSimdVector &b, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_add_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _add(TSimdVector &a, TSimdVector &b, SimdParams_<32, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_add_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _sub (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _sub(TSimdVector &a, TSimdVector &b, SimdParams_<32, 32>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_sub_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _sub(TSimdVector &a, TSimdVector &b, SimdParams_<32, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_sub_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _sub(TSimdVector &a, TSimdVector &b, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_sub_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _sub(TSimdVector &a, TSimdVector &b, SimdParams_<32, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_sub_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _mult (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _mult(TSimdVector &a, TSimdVector &b, SimdParams_<32, 32>)
-{
-    SEQAN_ASSERT_FAIL("AVX2 intrinsics for multiplying 8 bit values not implemented!");
-    return a;
-}
-
-template <typename TSimdVector>
-inline TSimdVector _mult(TSimdVector &a, TSimdVector &b, SimdParams_<32, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_mullo_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                 SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _mult(TSimdVector &a, TSimdVector &b, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_mullo_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                                 SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _mult(TSimdVector &a, TSimdVector &b, SimdParams_<32, 4>)
-{
-    SEQAN_ASSERT_FAIL("AVX2 intrinsics for multiplying 64 bit values not implemented!");
-    return a;
-}
-
-// --------------------------------------------------------------------------
-// _max (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _max(TSimdVector &a, TSimdVector &b, SimdParams_<32, 32>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_max_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _max(TSimdVector &a, TSimdVector &b, SimdParams_<32, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_max_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _max(TSimdVector &a, TSimdVector &b, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_max_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _max(TSimdVector &a, TSimdVector &b, SimdParams_<32, 4>)
-{
-    SEQAN_ASSERT_FAIL("AVX2 intrinsics for max on 64 bit values not implemented!");
-    return a;
-}
-
-// --------------------------------------------------------------------------
-// _blend (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename TSimdVectorMask, int L>
-inline TSimdVector _blend(TSimdVector const &a, TSimdVector const &b, TSimdVectorMask const &mask, SimdParams_<32, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm256_blendv_epi8(SEQAN_VECTOR_CAST_(const __m256i &, a),
-                                                 SEQAN_VECTOR_CAST_(const __m256i &, b),
-                                                 SEQAN_VECTOR_CAST_(const __m256i &, mask)));
-}
-
-// --------------------------------------------------------------------------
-// _storeu (256bit)
-// --------------------------------------------------------------------------
-
-template <typename T, typename TSimdVector, int L>
-inline void _storeu(T * memAddr, TSimdVector &vec, SimdParams_<32, L>)
-{
-    _mm256_storeu_si256((__m256i*)memAddr, SEQAN_VECTOR_CAST_(const __m256i&, vec));
-}
-
-// ----------------------------------------------------------------------------
-// Function _load() 256bit
-// ----------------------------------------------------------------------------
-
-template <typename TSimdVector, typename T, int L>
-inline TSimdVector _load(T const * memAddr, SimdParams_<32, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_load_si256((__m256i const *) memAddr));
-}
-
-// --------------------------------------------------------------------------
-// _shuffleVector (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector1, typename TSimdVector2>
-inline TSimdVector1
-_shuffleVector(TSimdVector1 const &vector, TSimdVector2 const &indices, SimdParams_<32, 32>, SimdParams_<32, 32>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector1, _mm256_shuffle_epi8(SEQAN_VECTOR_CAST_(const __m256i &, vector),
-                                                                SEQAN_VECTOR_CAST_(const __m256i &, indices)));
-}
-template <typename TSimdVector1, typename TSimdVector2>
-inline TSimdVector1
-_shuffleVector(TSimdVector1 const &vector, TSimdVector2 const &indices, SimdParams_<32, 16>, SimdParams_<16, 16>)
-{
-    // copy 2nd 64bit word to 3rd, compute 2*idx
-    __m256i idx = _mm256_slli_epi16(_mm256_permute4x64_epi64(_mm256_castsi128_si256(SEQAN_VECTOR_CAST_(const __m128i &, indices)), 0x50), 1);
-
-    // interleave with 2*idx+1 and call shuffle
-    return SEQAN_VECTOR_CAST_(TSimdVector1, _mm256_shuffle_epi8(SEQAN_VECTOR_CAST_(const __m256i &, vector),
-                                                                _mm256_unpacklo_epi8(idx, _mm256_add_epi8(idx, _mm256_set1_epi8(1)))));
-}
-
-// --------------------------------------------------------------------------
-// _shiftRightLogical (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _shiftRightLogical(TSimdVector const &vector, const int imm, SimdParams_<32, 32>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_srli_epi16(SEQAN_VECTOR_CAST_(const __m256i &, vector), imm) & _mm256_set1_epi8(0xff >> imm));
-}
-template <typename TSimdVector>
-inline TSimdVector _shiftRightLogical(TSimdVector const &vector, const int imm, SimdParams_<32, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_srli_epi16(SEQAN_VECTOR_CAST_(const __m256i &, vector), imm));
-}
-template <typename TSimdVector>
-inline TSimdVector _shiftRightLogical(TSimdVector const &vector, const int imm, SimdParams_<32, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_srli_epi32(SEQAN_VECTOR_CAST_(const __m256i &, vector), imm));
-}
-template <typename TSimdVector>
-inline TSimdVector _shiftRightLogical(TSimdVector const &vector, const int imm, SimdParams_<32, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_srli_epi64(SEQAN_VECTOR_CAST_(const __m256i &, vector), imm));
-}
-
-// --------------------------------------------------------------------------
-// _gather (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TValue, typename TSimdVector, typename TSize, TSize SCALE>
-inline TSimdVector _gather(TValue const * memAddr,
-                           TSimdVector const & idx,
-                           std::integral_constant<TSize, SCALE> const & /*scale*/,
-                           SimdParams_<32, 16>)
-{
-    // 1. Unpack low idx values and interleave with 0 and gather from memAddr.
-    // 2. Unpack high idx values and interleave with 0, than gather from memAddr.
-    // 3. Merge 2 8x32 vectors into 1x16 vector by signed saturation. This operation reverts the interleave by the unpack operations above.
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_packs_epi32(_mm256_i32gather_epi32(static_cast<int32_t const *>(memAddr), _mm256_unpacklo_epi16(SEQAN_VECTOR_CAST_(__m256i const &, idx), _mm256_set1_epi16(0)), SCALE),
-                                                              _mm256_i32gather_epi32(static_cast<int32_t const *>(memAddr), _mm256_unpackhi_epi16(SEQAN_VECTOR_CAST_(__m256i const &, idx), _mm256_set1_epi16(0)), SCALE)));
-}
-
-// --------------------------------------------------------------------------
-// _transposeMatrix (256bit)
-// --------------------------------------------------------------------------
-
-// emulate missing _mm256_unpacklo_epi128/_mm256_unpackhi_epi128 instructions
-inline __m256i _mm256_unpacklo_epi128(__m256i const &a, __m256i const &b)
-{
-    return _mm256_permute2x128_si256(a, b, 0x20);
-//    return _mm256_inserti128_si256(a, _mm256_extracti128_si256(b, 0), 1);
-}
-
-inline __m256i _mm256_unpackhi_epi128(__m256i const &a, __m256i const &b)
-{
-    return _mm256_permute2x128_si256(a, b, 0x31);
-//    return _mm256_inserti128_si256(b, _mm256_extracti128_si256(a, 1), 0);
-}
-
-template <typename TSimdVector>
-inline void
-_transposeMatrix(TSimdVector matrix[], SimdMatrixParams_<32, 32, 8>)
-{
-    // we need a look-up table to reverse the lowest 4 bits
-    // in order to place the permute the transposed rows
-    static const unsigned char bitRev[] = { 0, 8, 4,12, 2,10, 6,14, 1, 9, 5,13, 3,11, 7,15,
-                                           16,24,20,28,18,26,22,30,17,25,21,29,19,27,23,31};
-
-    // transpose a 32x32 byte matrix
-    __m256i tmp1[32];
-    for (int i = 0; i < 16; ++i)
-    {
-        tmp1[i]    = _mm256_unpacklo_epi8(SEQAN_VECTOR_CAST_(const __m256i &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m256i &, matrix[2*i+1]));
-        tmp1[i+16] = _mm256_unpackhi_epi8(SEQAN_VECTOR_CAST_(const __m256i &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m256i &, matrix[2*i+1]));
-    }
-    __m256i  tmp2[32];
-    for (int i = 0; i < 16; ++i)
-    {
-        tmp2[i]    = _mm256_unpacklo_epi16(tmp1[2*i], tmp1[2*i+1]);
-        tmp2[i+16] = _mm256_unpackhi_epi16(tmp1[2*i], tmp1[2*i+1]);
-    }
-    for (int i = 0; i < 16; ++i)
-    {
-        tmp1[i]    = _mm256_unpacklo_epi32(tmp2[2*i], tmp2[2*i+1]);
-        tmp1[i+16] = _mm256_unpackhi_epi32(tmp2[2*i], tmp2[2*i+1]);
-    }
-    for (int i = 0; i < 16; ++i)
-    {
-        tmp2[i]    = _mm256_unpacklo_epi64(tmp1[2*i], tmp1[2*i+1]);
-        tmp2[i+16] = _mm256_unpackhi_epi64(tmp1[2*i], tmp1[2*i+1]);
-    }
-    for (int i = 0; i < 16; ++i)
-    {
-        matrix[bitRev[i]]    = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_unpacklo_epi128(tmp2[2*i],tmp2[2*i+1]));
-        matrix[bitRev[i+16]] = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_unpackhi_epi128(tmp2[2*i],tmp2[2*i+1]));
-    }
-}
-
-// --------------------------------------------------------------------------
-// Function _testAllZeros (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, int)
-inline _testAllZeros(TSimdVector const &vector, TSimdVector const &mask, SimdParams_<32>)
-{
-    return _mm256_testz_si256(SEQAN_VECTOR_CAST_(const __m256i &, vector),
-                              SEQAN_VECTOR_CAST_(const __m256i &, mask));
-}
-
-// --------------------------------------------------------------------------
-// Function _testAllOnes (256bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline int _testAllOnes(TSimdVector const &vector, SimdParams_<32>)
-{
-    __m256i vec = SEQAN_VECTOR_CAST_(const __m256i &, vector);
-    return _mm256_testc_si256(vec, _mm256_cmpeq_epi32(vec, vec));
-}
-
-#endif  // #ifdef __AVX2__
-
-// ============================================================================
-// SSE3 wrappers (128bit vectors)
-// ============================================================================
-
-#ifdef SEQAN_SSE4
-
-// --------------------------------------------------------------------------
-// _fillVector (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename... TValue>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & x, std::index_sequence<0> const &, SimdParams_<16, 16>) { SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set1_epi8(std::get<0>(x)); }
-template <typename TSimdVector, typename... TValue>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & x, std::index_sequence<0> const &, SimdParams_<16, 8>)  { SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set1_epi16(std::get<0>(x)); }
-template <typename TSimdVector, typename... TValue>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & x, std::index_sequence<0> const &, SimdParams_<16, 4>)  { SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set1_epi32(std::get<0>(x)); }
-template <typename TSimdVector, typename... TValue>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & x, std::index_sequence<0> const &, SimdParams_<16, 2>)  { SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set1_epi64x(std::get<0>(x)); }
-template <typename TSimdVector>
-inline void _fillVector(TSimdVector &vector, std::tuple<float> const & x,  std::index_sequence<0> const &, SimdParams_<16, 4>)   { SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set1_ps(std::get<0>(x)); }
-template <typename TSimdVector>
-inline void _fillVector(TSimdVector &vector, std::tuple<double> const & x, std::index_sequence<0> const &, SimdParams_<16, 2>)  { SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set1_pd(std::get<0>(x)); }
-
-template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & args, std::index_sequence<INDICES...> const &, SimdParams_<16, 16>)
-{
-    SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set_epi8(std::get<INDICES>(args)...);
-}
-
-template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & args, std::index_sequence<INDICES...> const &, SimdParams_<16, 8>)
-{
-    SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set_epi16(std::get<INDICES>(args)...);
-}
-
-template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & args, std::index_sequence<INDICES...> const &, SimdParams_<16, 4>)
-{
-    SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set_epi32(std::get<INDICES>(args)...);
-}
-
-template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
-inline void _fillVector(TSimdVector &vector, std::tuple<TValue...> const & args, std::index_sequence<INDICES...> const &, SimdParams_<16, 2>)
-{
-    SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_set_epi64x(std::get<INDICES>(args)...);
-}
-
-// --------------------------------------------------------------------------
-// _clearVector (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, int L>
-inline void _clearVector(TSimdVector &vector, SimdParams_<16, L>) { SEQAN_VECTOR_CAST_LVALUE_(__m128i&, vector) = _mm_setzero_si128(); }
-template <typename TSimdVector>
-inline void _clearVector(TSimdVector &vector, SimdParams_<16, 4>)  { SEQAN_VECTOR_CAST_LVALUE_(__m128&, vector) = _mm_setzero_ps(); }
-template <typename TSimdVector>
-inline void _clearVector(TSimdVector &vector, SimdParams_<16, 2>)  { SEQAN_VECTOR_CAST_LVALUE_(__m128d&, vector) = _mm_setzero_pd(); }
-
-// --------------------------------------------------------------------------
-// _createVector (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename TValue>
-inline TSimdVector _createVector(TValue x, SimdParams_<16, 16>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi8(x)); }
-template <typename TSimdVector, typename TValue>
-inline TSimdVector _createVector(TValue x, SimdParams_<16, 8>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi16(x)); }
-template <typename TSimdVector, typename TValue>
-inline TSimdVector _createVector(TValue x, SimdParams_<16, 4>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi32(x)); }
-template <typename TSimdVector, typename TValue>
-inline TSimdVector _createVector(TValue x, SimdParams_<16, 2>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi64x(x)); }
-template <typename TSimdVector>
-inline TSimdVector _createVector(float x,  SimdParams_<16, 4>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_ps(x)); }
-template <typename TSimdVector>
-inline TSimdVector _createVector(double x, SimdParams_<16, 2>)  { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_pd(x)); }
-
-// --------------------------------------------------------------------------
-// cmpEq (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _cmpEq(TSimdVector &a, TSimdVector &b, SimdParams_<16, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpeq_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                             SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpEq(TSimdVector &a, TSimdVector &b, SimdParams_<16, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpeq_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpEq(TSimdVector &a, TSimdVector &b, SimdParams_<16, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpeq_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpEq(TSimdVector &a, TSimdVector &b, SimdParams_<16, 2>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpeq_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _cmpGt (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _cmpGt(TSimdVector &a, TSimdVector &b, SimdParams_<16, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpgt_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                             SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpGt(TSimdVector &a, TSimdVector &b, SimdParams_<16, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpgt_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpGt(TSimdVector &a, TSimdVector &b, SimdParams_<16, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpgt_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _cmpGt(TSimdVector &a, TSimdVector &b, SimdParams_<16, 2>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpgt_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _bitwiseOr (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, int L>
-inline TSimdVector _bitwiseOr(TSimdVector &a, TSimdVector &b, SimdParams_<16, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_or_si128(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _bitwiseAnd (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, int L>
-inline TSimdVector _bitwiseAnd(TSimdVector &a, TSimdVector &b, SimdParams_<16, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_and_si128(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _bitwiseAndNot (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, int L>
-inline TSimdVector _bitwiseAndNot(TSimdVector &a, TSimdVector &b, SimdParams_<16, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_andnot_si128(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                               SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _bitwiseNot (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseNot(TSimdVector &a, SimdParams_<16, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpeq_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                             _mm_setzero_si128()));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseNot(TSimdVector &a, SimdParams_<16, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpeq_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              _mm_setzero_si128()));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseNot(TSimdVector &a, SimdParams_<16, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpeq_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              _mm_setzero_si128()));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _bitwiseNot(TSimdVector &a, SimdParams_<16, 2>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_cmpeq_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              _mm_setzero_si128()));
-}
-
-// --------------------------------------------------------------------------
-// _divide (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _divide(TSimdVector &a, int b, SimdParams_<16, 16>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_div_epi8(a, _mm_set1_epi8(b))); }
-
-template <typename TSimdVector>
-inline TSimdVector _divide(TSimdVector &a, int b, SimdParams_<16, 8>){ return SEQAN_VECTOR_CAST_(TSimdVector, _mm_div_epi16(a, _mm_set1_epi16(b))); }
-
-template <typename TSimdVector>
-inline TSimdVector _divide(TSimdVector &a, int b, SimdParams_<16, 4>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_div_epi32(a, _mm_set1_epi32(b))); }
-
-template <typename TSimdVector>
-inline TSimdVector _divide(TSimdVector &a, int b, SimdParams_<16, 2>) { return SEQAN_VECTOR_CAST_(TSimdVector, _mm_div_epi64(a, _mm_set1_epi64x(b))); }
-
-// --------------------------------------------------------------------------
-// _add (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _add(TSimdVector &a, TSimdVector &b, SimdParams_<16, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_add_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _add(TSimdVector &a, TSimdVector &b, SimdParams_<16, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_add_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _add(TSimdVector &a, TSimdVector &b, SimdParams_<16, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_add_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _add(TSimdVector &a, TSimdVector &b, SimdParams_<16, 2>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_add_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _sub (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _sub(TSimdVector &a, TSimdVector &b, SimdParams_<16, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_sub_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _sub(TSimdVector &a, TSimdVector &b, SimdParams_<16, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_sub_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _sub(TSimdVector &a, TSimdVector &b, SimdParams_<16, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_sub_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _sub(TSimdVector &a, TSimdVector &b, SimdParams_<16, 2>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_sub_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _mult (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _mult(TSimdVector &a, TSimdVector &/*b*/, SimdParams_<16, 16>)
-{
-    SEQAN_ASSERT_FAIL("SSE intrinsics for multiplying 8 bit values not implemented!");
-    return a;
-}
-
-template <typename TSimdVector>
-inline TSimdVector _mult(TSimdVector &a, TSimdVector &b, SimdParams_<16, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_mullo_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _mult(TSimdVector &a, TSimdVector &b, SimdParams_<16, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_mullo_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _mult(TSimdVector &a, TSimdVector &/*b*/, SimdParams_<16, 2>)
-{
-    SEQAN_ASSERT_FAIL("SSE intrinsics for multiplying 64 bit values not implemented!");
-    return a;
-}
-
-// --------------------------------------------------------------------------
-// _max (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _max(TSimdVector &a, TSimdVector &b, SimdParams_<16, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_max_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _max(TSimdVector &a, TSimdVector &b, SimdParams_<16, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_max_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-template <typename TSimdVector>
-inline TSimdVector _max(TSimdVector &a, TSimdVector &b, SimdParams_<16, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_max_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
-}
-
-// --------------------------------------------------------------------------
-// _blend (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename TSimdVectorMask, int L>
-inline TSimdVector _blend(TSimdVector const &a, TSimdVector const &b, TSimdVectorMask const &mask, SimdParams_<16, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector,
-                              _mm_blendv_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, b),
-                                              SEQAN_VECTOR_CAST_(const __m128i&, mask)));
-}
-
-// --------------------------------------------------------------------------
-// _storeu (128bit)
-// --------------------------------------------------------------------------
-
-template <typename T, typename TSimdVector, int L>
-inline void _storeu(T * memAddr, TSimdVector &vec, SimdParams_<16, L>)
-{
-    _mm_storeu_si128((__m128i*)memAddr, reinterpret_cast<const __m128i &>(vec));
-}
-
-// ----------------------------------------------------------------------------
-// Function _load() 128bit
-// ----------------------------------------------------------------------------
-
-template <typename TSimdVector, typename T, int L>
-inline TSimdVector _load(T const * memAddr, SimdParams_<16, L>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_load_si128((__m128i const *) memAddr));
-}
-
-// --------------------------------------------------------------------------
-// _shuffleVector (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector1, typename TSimdVector2>
-inline TSimdVector1
-_shuffleVector(TSimdVector1 const &vector, TSimdVector2 const &indices, SimdParams_<16, 16>, SimdParams_<16, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector1, _mm_shuffle_epi8(SEQAN_VECTOR_CAST_(const __m128i &, vector),
-                                                             SEQAN_VECTOR_CAST_(const __m128i &, indices)));
-}
-
-template <typename TSimdVector1, typename TSimdVector2>
-inline TSimdVector1
-_shuffleVector(TSimdVector1 const &vector, TSimdVector2 const &indices, SimdParams_<16, 8>, SimdParams_<8, 8>)
-{
-#if SEQAN_IS_32_BIT
-    __m128i idx = _mm_slli_epi16(_mm_unpacklo_epi32(_mm_cvtsi32_si128(reinterpret_cast<const uint32_t &>(indices)),
-                                                    _mm_cvtsi32_si128(reinterpret_cast<const uint64_t &>(indices) >> 32)), 1);
-#else
-    __m128i idx = _mm_slli_epi16(_mm_cvtsi64_si128(reinterpret_cast<const uint64_t &>(indices)), 1);
-#endif  // SEQAN_IS_32_BIT
-    return SEQAN_VECTOR_CAST_(TSimdVector1, _mm_shuffle_epi8(SEQAN_VECTOR_CAST_(const __m128i &, vector),
-                                                             _mm_unpacklo_epi8(idx, _mm_add_epi8(idx, _mm_set1_epi8(1)))));
-}
-
-// --------------------------------------------------------------------------
-// _shiftRightLogical (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline TSimdVector _shiftRightLogical(TSimdVector const &vector, const int imm, SimdParams_<16, 16>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_srli_epi16(SEQAN_VECTOR_CAST_(const __m128i &, vector), imm) & _mm_set1_epi8(0xff >> imm));
-}
-template <typename TSimdVector>
-inline TSimdVector _shiftRightLogical(TSimdVector const &vector, const int imm, SimdParams_<16, 8>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_srli_epi16(SEQAN_VECTOR_CAST_(const __m128i &, vector), imm));
-}
-template <typename TSimdVector>
-inline TSimdVector _shiftRightLogical(TSimdVector const &vector, const int imm, SimdParams_<16, 4>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_srli_epi32(SEQAN_VECTOR_CAST_(const __m128i &, vector), imm));
-}
-template <typename TSimdVector>
-inline TSimdVector _shiftRightLogical(TSimdVector const &vector, const int imm, SimdParams_<16, 2>)
-{
-    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_srli_epi64(SEQAN_VECTOR_CAST_(const __m128i &, vector), imm));
-}
-
-// --------------------------------------------------------------------------
-// _transposeMatrix (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline void
-_transposeMatrix(TSimdVector matrix[], SimdMatrixParams_<8, 8, 8>)
-{
-    // we need a look-up table to reverse the lowest 4 bits
-    // in order to place the permute the transposed rows
-    static const unsigned char bitRev[] = {0,4,2,6,1,5,3,7};
-
-    // transpose a 8x8 byte matrix
-    __m64 tmp1[8];
-    for (int i = 0; i < 4; ++i)
-    {
-        tmp1[i]   = _mm_unpacklo_pi8(SEQAN_VECTOR_CAST_(const __m64 &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m64 &, matrix[2*i+1]));
-        tmp1[i+4] = _mm_unpackhi_pi8(SEQAN_VECTOR_CAST_(const __m64 &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m64 &, matrix[2*i+1]));
-    }
-    __m64 tmp2[8];
-    for (int i = 0; i < 4; ++i)
-    {
-        tmp2[i]   = _mm_unpacklo_pi16(tmp1[2*i], tmp1[2*i+1]);
-        tmp2[i+4] = _mm_unpackhi_pi16(tmp1[2*i], tmp1[2*i+1]);
-    }
-    for (int i = 0; i < 4; ++i)
-    {
-        matrix[bitRev[i]]   = SEQAN_VECTOR_CAST_(TSimdVector, _mm_unpacklo_pi32(tmp2[2*i], tmp2[2*i+1]));
-        matrix[bitRev[i+4]] = SEQAN_VECTOR_CAST_(TSimdVector, _mm_unpackhi_pi32(tmp2[2*i], tmp2[2*i+1]));
-    }
-}
-
-template <typename TSimdVector>
-inline void
-_transposeMatrix(TSimdVector matrix[], SimdMatrixParams_<16, 16, 8>)
-{
-    // we need a look-up table to reverse the lowest 4 bits
-    // in order to place the permute the transposed rows
-    static const unsigned char bitRev[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
-
-    // transpose a 16x16 byte matrix
-    //
-    // matrix =
-    // A0 A1 A2 ... Ae Af
-    // B0 B1 B2 ... Be Bf
-    // ...
-    // P0 P1 P2 ... Pe Pf
-    __m128i tmp1[16];
-    for (int i = 0; i < 8; ++i)
-    {
-        tmp1[i]   = _mm_unpacklo_epi8(SEQAN_VECTOR_CAST_(const __m128i &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m128i &, matrix[2*i+1]));
-        tmp1[i+8] = _mm_unpackhi_epi8(SEQAN_VECTOR_CAST_(const __m128i &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m128i &, matrix[2*i+1]));
-    }
-    // tmp1[0]  = A0 B0 A1 B1 ... A7 B7
-    // tmp1[1]  = C0 D0 C1 D1 ... C7 D7
-    // ...
-    // tmp1[7]  = O0 P0 O1 P1 ... O7 P7
-    // tmp1[8]  = A8 B8 A9 B9 ... Af Bf
-    // ...
-    // tmp1[15] = O8 P8 O9 P9 ... Of Pf
-    __m128i tmp2[16];
-    for (int i = 0; i < 8; ++i)
-    {
-        tmp2[i]   = _mm_unpacklo_epi16(tmp1[2*i], tmp1[2*i+1]);
-        tmp2[i+8] = _mm_unpackhi_epi16(tmp1[2*i], tmp1[2*i+1]);
-    }
-    // tmp2[0]  = A0 B0 C0 D0 ... A3 B3 C3 D3
-    // tmp2[1]  = E0 F0 G0 H0 ... E3 F3 G3 H3
-    // ...
-    // tmp2[3]  = M0 N0 O0 P0 ... M3 N3 O3 P3
-    // tmp2[4]  = A8 B8 C8 D8 ... Ab Bb Cb Db
-    // ...
-    // tmp2[7]  = M8 N8 O8 P8 ... Mb Nb Ob Pb
-    // tmp2[8]  = A4 B4 C4 D4 ... A7 B7 C7 D7
-    // ..
-    // tmp2[12] = Ac Bc Cc Dc ... Af Bf Cf Df
-    // ...
-    // tmp2[15] = Mc Nc Oc Pc ... Mf Nf Of Pf
-    for (int i = 0; i < 8; ++i)
-    {
-        tmp1[i]   = _mm_unpacklo_epi32(tmp2[2*i], tmp2[2*i+1]);
-        tmp1[i+8] = _mm_unpackhi_epi32(tmp2[2*i], tmp2[2*i+1]);
-    }
-    // tmp1[0]  = A0 B0 .... H0 A1 B1 .... H1
-    // tmp1[1]  = I0 J0 .... P0 I1 J1 .... P1
-    // ...
-    // tmp1[4]  = A0 B0 .... H0 A1 B1 .... H1
-    // tmp1[1]  = I0 J0 .... P0 I1 J1 .... P1
-    for (int i = 0; i < 8; ++i)
-    {
-        matrix[bitRev[i]]   = SEQAN_VECTOR_CAST_(TSimdVector, _mm_unpacklo_epi64(tmp1[2*i], tmp1[2*i+1]));
-        matrix[bitRev[i+8]] = SEQAN_VECTOR_CAST_(TSimdVector, _mm_unpackhi_epi64(tmp1[2*i], tmp1[2*i+1]));
-    }
-}
-
-// --------------------------------------------------------------------------
-// Function _testAllZeros (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, int)
-inline _testAllZeros(TSimdVector const &vector, TSimdVector const &mask, SimdParams_<16>)
-{
-    return _mm_testz_si128(vector, mask);
-}
-
-// --------------------------------------------------------------------------
-// Function _testAllOnes (128bit)
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline
-SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, int)
-_testAllOnes(TSimdVector const &vector, SimdParams_<16>)
-{
-    return _mm_test_all_ones(SEQAN_VECTOR_CAST_(const __m128i &, vector));
-}
-#endif  // #ifdef SEQAN_SSE4
-
-// ============================================================================
-//
-// INTERFACE FUNCTIONS
-// - these should be used in the actual code, they will call one of the wrapper
-//   functions defined above based on the vector type
-//
-// ============================================================================
-
-// --------------------------------------------------------------------------
-// Function transpose()
-// --------------------------------------------------------------------------
-
-template <int ROWS, typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
-transpose(TSimdVector matrix[ROWS])
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    _transposeMatrix(matrix, SimdMatrixParams_<ROWS, LENGTH<TSimdVector>::VALUE, BitsPerValue<TValue>::VALUE>());
-}
-
-// --------------------------------------------------------------------------
-// Function clearVector()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
-clearVector(TSimdVector &vector)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    _clearVector(vector, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function createVector()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename TValue>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-createVector(TValue x)
-{
-    typedef typename Value<TSimdVector>::Type TIVal;
-    return _createVector<TSimdVector>(x, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TIVal)>());
-}
-
-// --------------------------------------------------------------------------
-// Function fillVector()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename ...TValue>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
-fillVector(TSimdVector &vector, TValue const... args)
-{
-    typedef typename Value<TSimdVector>::Type TIVal;
-    _fillVector(vector, std::make_tuple(args...),
-                std::make_index_sequence<sizeof...(args)>{},
-                SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TIVal)>());
-}
-
-// --------------------------------------------------------------------------
-// Function cmpEq()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-cmpEq (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _cmpEq(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator==()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator == (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _cmpEq(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operatorGt()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-cmpGt (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _cmpGt(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator>()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator > (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _cmpGt(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function max()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-max(TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _max(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator|()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator | (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _bitwiseOr(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator|=()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector &)
-operator |= (TSimdVector &a, TSimdVector const &b)
-{
-    a = a | b;
-    return a;
-}
-
-// --------------------------------------------------------------------------
-// Function operator&()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator & (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _bitwiseAnd(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator&=()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector &)
-operator &= (TSimdVector &a, TSimdVector const &b)
-{
-    a = a & b;
-    return a;
-}
-
-// --------------------------------------------------------------------------
-// Function operator~()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator ~ (TSimdVector const &a)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _bitwiseNot(a, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator+()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator + (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _add(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator-()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator - (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _sub(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator*()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator * (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _mult(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function operator/()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-operator/ (TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _div(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function andNot
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-andNot(TSimdVector const &a, TSimdVector const &b)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _bitwiseAndNot(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function shuffleVector()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector1, typename TSimdVector2>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector1> >, TSimdVector1)
-shuffleVector(TSimdVector1 const &vector, TSimdVector2 const &indices)
-{
-    typedef typename Value<TSimdVector1>::Type TValue1;
-    typedef typename Value<TSimdVector2>::Type TValue2;
-    return _shuffleVector(
-                vector,
-                indices,
-                SimdParams_<sizeof(TSimdVector1), sizeof(TSimdVector1) / sizeof(TValue1)>(),
-                SimdParams_<sizeof(TSimdVector2), sizeof(TSimdVector2) / sizeof(TValue2)>());
-}
-
-// --------------------------------------------------------------------------
-// Function shiftRightLogical()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-shiftRightLogical(TSimdVector const &vector, const int imm)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _shiftRightLogical(vector, imm, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function blend()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename TSimdVectorMask>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-blend(TSimdVector const &a, TSimdVector const &b, TSimdVectorMask const & mask)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _blend(a, b, mask, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function storeu()
-// --------------------------------------------------------------------------
-
-template <typename T, typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
-storeu(T * memAddr, TSimdVector const &vec)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    _storeu(memAddr, vec, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function load()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector, typename T>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-load(T const * memAddr)
-{
-    typedef typename Value<TSimdVector>::Type TValue;
-    return _load<TSimdVector>(memAddr, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
-}
-
-// --------------------------------------------------------------------------
-// Function gather()
-// --------------------------------------------------------------------------
-
-template <typename TValue, typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-gather(TValue const * memAddr, TSimdVector const & idx)
-{
-    typedef typename Value<TSimdVector>::Type TInnerValue;
-    return _gather(memAddr, idx, std::integral_constant<size_t, sizeof(TValue)>(), SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TInnerValue)>());
-}
-
-#endif  // SEQAN_SIMD_ENABLED
-
-// NOTE(rmaerker): Make this function available, also if SIMD is not enabled.
-template <typename TSimdVector, typename TValue>
-inline SEQAN_FUNC_DISABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-createVector(TValue x)
-{
-    return x;
-}
-
-// --------------------------------------------------------------------------
-// Function print()
-// --------------------------------------------------------------------------
-
-template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, std::ostream &)
-print(std::ostream &stream, TSimdVector const &vector)
-{
-    stream << '<';
-    for (int i = 0; i < LENGTH<TSimdVector>::VALUE; ++i)
-    stream << '\t' << vector[i];
-    stream << "\t>\n";
-    return stream;
-}
-
-} // namespace seqan
-
-#endif // SEQAN_INCLUDE_SEQAN_BASIC_SIMD_VECTOR_H_
diff --git a/include/seqan/basic/basic_stream.h b/include/seqan/basic/basic_stream.h
index e03dca2..d277730 100644
--- a/include/seqan/basic/basic_stream.h
+++ b/include/seqan/basic/basic_stream.h
@@ -1190,18 +1190,37 @@ formattedNumber(const char *format, TValue const & val)
 
 template <typename TTarget, typename TValue>
 inline void
-appendRawPod(TTarget & target, TValue const & val)
+appendRawPodImpl(TTarget & target, TValue const & val)
 {
     write(target, (unsigned char*)&val, sizeof(TValue));
 }
 
 template <typename TTargetValue, typename TValue>
 inline void
-appendRawPod(TTargetValue * &ptr, TValue const & val)
+appendRawPodImpl(TTargetValue * &ptr, TValue const & val)
 {
     *reinterpret_cast<TValue* &>(ptr)++ = val;
 }
 
+template <typename TTarget, typename TValue>
+inline std::enable_if_t<std::is_arithmetic<TValue>::value>
+appendRawPod(TTarget & target, TValue val)
+{
+    ensure_little_endian(val);
+    appendRawPodImpl(target, val);
+}
+
+template <typename TTarget, typename TValue>
+inline std::enable_if_t<!std::is_arithmetic<TValue>::value>
+appendRawPod(TTarget & target, TValue const & val)
+{
+#if SEQAN_BIG_ENDIAN
+    #error "You are serialising a data structure on big endian architecture that needs a custom writer. THIS IS A BUG!"
+#else
+    appendRawPodImpl(target, val);
+#endif
+}
+
 // ----------------------------------------------------------------------------
 // Function write(TNumber); write fundamental type
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/basic/debug_test_system.h b/include/seqan/basic/debug_test_system.h
index d98d4e2..410ab6c 100644
--- a/include/seqan/basic/debug_test_system.h
+++ b/include/seqan/basic/debug_test_system.h
@@ -1731,10 +1731,10 @@ inline void fail()
 
 // This macro returns from the current function and logs a "skipped"
 // event for the current test.
-#define SEQAN_SKIP_TEST                         \
-    do {                                        \
-        ::seqan::ClassTest::skipCurrentTest();  \
-        return;                                 \
+#define SEQAN_SKIP_TEST                                       \
+    do {                                                      \
+        ::seqan::ClassTest::skipCurrentTest();                \
+        throw ::seqan::ClassTest::AssertionFailedException(); \
     } while (false)
 #endif  // #if SEQAN_ENABLE_TESTING
 
diff --git a/include/seqan/blast/blast_statistics.h b/include/seqan/blast/blast_statistics.h
index 98624ac..567d654 100644
--- a/include/seqan/blast/blast_statistics.h
+++ b/include/seqan/blast/blast_statistics.h
@@ -1117,9 +1117,11 @@ computeEValue(uint64_t rawScore,
 /*!
  * @fn BlastMatch#computeEValue
  * @brief Compute the E-Value for a @link BlastMatch @endlink.
- * @signature double computeEValue(blastMatch, context);
+ * @signature double computeEValue(blastMatch, qLength, context);
+ * [[deprecated]] double computeEValue(blastMatch, context);
  *
  * @param[in,out]   blastMatch  A @link BlastMatch @endlink that has a valid align member.
+ * @param[in]       qLength     The length of the query sequence (pass @link BlastRecord::qLength @endlink).
  * @param[in,out]   context     A @link BlastIOContext @endlink with parameters and buffers.
  *
  * @return double blastMatch. at link BlastMatch::eValue @endlink after computation
@@ -1132,7 +1134,7 @@ computeEValue(uint64_t rawScore,
  * <li> blastMatch. at link BlastMatch::alignStats @endlink. at link AlignmentStats::alignmentScore @endlink (if you have valid
  * alignRow-members (@link BlastMatch::alignRow0 @endlink, @link BlastMatch::alignRow1 @endlink), you can call
  * @link BlastMatch#computeAlignmentStats @endlink to compute the stats member). </li>
- * <li> blastMatch. at link BlastMatch::qLength @endlink </li>
+ * <li> blastMatch. at link BlastMatch::qLength @endlink (only in the deprecated interface)</li>
  * <li> context. at link BlastIOContext::dbTotalLength @endlink </li>
  *
  * Note, that in contrast to the general interface (@link BlastScoringScheme#computeEValue @endlink), this interface
@@ -1145,10 +1147,13 @@ template <typename TBlastMatch,
           BlastTabularSpec h>
 inline double
 computeEValue(TBlastMatch & match,
+              uint64_t ql,
               BlastIOContext<TScore, p, h> & context)
 {
+    SEQAN_ASSERT_GT(ql, 0ull);
+
     // convert to 64bit and divide for translated sequences
-    uint64_t ql = match.qLength / (qIsTranslated(context.blastProgram) ? 3 : 1);
+    ql = ql / (qIsTranslated(context.blastProgram) ? 3 : 1);
     // length adjustment not yet computed
     if (context._cachedLengthAdjustments.find(ql) == context._cachedLengthAdjustments.end())
         context._cachedLengthAdjustments[ql] = _lengthAdjustment(context.dbTotalLength, ql, context.scoringScheme);
@@ -1162,6 +1167,18 @@ computeEValue(TBlastMatch & match,
     return match.eValue;
 }
 
+template <typename TBlastMatch,
+          typename TScore,
+          BlastProgram p,
+          BlastTabularSpec h>
+[[deprecated("Use the interface with an explicit query length parameter instead (use the record's member).")]]
+inline double
+computeEValue(TBlastMatch & match,
+              BlastIOContext<TScore, p, h> & context)
+{
+    return computeEValue(match, match.qLength, context);
+}
+
 }
 
 #endif // ndef __BLAST_STATISTICS_H__
diff --git a/include/seqan/graph_algorithms/maximum_weighted_matching.h b/include/seqan/graph_algorithms/maximum_weighted_matching.h
new file mode 100644
index 0000000..d987b49
--- /dev/null
+++ b/include/seqan/graph_algorithms/maximum_weighted_matching.h
@@ -0,0 +1,246 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Joerg Winkler <j.winkler at fu-berlin.de>
+// ==========================================================================
+// Implementation for maximum weighted matching for general graphs.
+// The implemented algorithm is the greedy algorithm with a look-ahead.
+// That means the weight is maximized among the BLOCKSIZE heaviest edges.
+// The performance ratio of this algorithm is 1/2.
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_GRAPH_ALGORITHMS_MAXIMUM_WEIGHTED_MATCHING_H_
+#define INCLUDE_SEQAN_GRAPH_ALGORITHMS_MAXIMUM_WEIGHTED_MATCHING_H_
+
+#include <utility>
+#include <algorithm>
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Function maximumWeightedMatchingGreedy()
+// ----------------------------------------------------------------------------
+
+typedef std::vector<std::pair<std::size_t, std::size_t> > TConflictVect;
+
+template <long unsigned BLOCKSIZE, typename TCargo>
+inline TCargo _evaluateConflicts(uint32_t & isUsed, std::array<TCargo, BLOCKSIZE> const & weights,
+                                 TConflictVect const & conflicts)
+{
+    // first variant (eliminate second element of pair, which is smaller)
+    std::size_t eliminate = conflicts.front().second;
+    TConflictVect remainingConflicts;
+    std::copy_if(conflicts.begin(), conflicts.end(), std::back_inserter(remainingConflicts),
+                 [&eliminate] (std::pair<std::size_t, std::size_t> const & conflict)
+    {
+        return conflict.first != eliminate && conflict.second != eliminate;
+    });
+    TCargo excludedWeight1 = weights[eliminate];
+    uint32_t isUsed1 = isUsed;
+    if (!remainingConflicts.empty())
+        excludedWeight1 += _evaluateConflicts(isUsed1, weights, remainingConflicts);
+
+    // second variant (eliminate first element of pair, which is larger)
+    eliminate = conflicts.front().first;
+    TCargo excludedWeight2 = weights[eliminate];
+
+    // trim traversion if weight2 is too high
+    if (excludedWeight1 <= excludedWeight2)
+    {
+        isUsed = isUsed1 & ~(1 << conflicts.front().second);  // delete bit for 2nd element
+        return excludedWeight1;
+    }
+
+    bool noDependency = conflicts.size() - remainingConflicts.size() == 1u;
+    remainingConflicts.clear();
+    std::copy_if(conflicts.begin(), conflicts.end(), std::back_inserter(remainingConflicts),
+                 [&eliminate] (std::pair<std::size_t, std::size_t> const & conflict)
+    {
+        return conflict.first != eliminate && conflict.second != eliminate;
+    });
+
+    // trim traversion if the removal of the first conflict does not influence any other conflict
+    if (noDependency && conflicts.size() - remainingConflicts.size() == 1u)
+    {
+        isUsed = isUsed1 & ~(1 << conflicts.front().second);  // delete bit for 2nd element
+        return excludedWeight1;
+    }
+
+    uint32_t isUsed2 = isUsed;
+    if (!remainingConflicts.empty())
+        excludedWeight2 += _evaluateConflicts(isUsed2, weights, remainingConflicts);
+
+    // evaluate variants
+    if (excludedWeight1 < excludedWeight2)
+    {  // use first variant
+        isUsed = isUsed1 & ~(1 << conflicts.front().second);  // take isUsed1 and delete bit (eliminate 2nd of pair)
+        return excludedWeight1;
+    }
+    else
+    {  // use second variant
+        isUsed = isUsed2 & ~(1 << conflicts.front().first);  // take isUsed2 and delete bit (eliminate 1st of pair)
+        return excludedWeight2;
+    }
+}
+
+// Compute greedy MWM (performance ratio 1/2)
+// look into BLOCKSIZE edges at once and maximize their weight
+template <long unsigned BLOCKSIZE = 1, typename TCargo>
+TCargo maximumWeightedMatchingGreedy(Graph<Undirected<TCargo> > const & graph)
+{
+    typedef Graph<Undirected<TCargo> > TUGraph;
+    typedef typename EdgeDescriptor<TUGraph>::Type TEdgeDescr;
+    typedef typename Iterator<TUGraph, EdgeIterator>::Type TEdgeIter;
+    typedef typename Iterator<TUGraph, AdjacencyIterator>::Type TAdjacIterator;
+    typedef typename VertexDescriptor<TUGraph>::Type TVertexDescr;
+
+    // set up edge vector and bit vector for conflicting edges
+    std::vector<TEdgeIter> edges;
+    std::vector<bool> conflictFree;
+    reserve(edges, numEdges(graph));
+    resize(conflictFree, numEdges(graph), true);
+
+    for (TEdgeIter edgeIt(graph); !atEnd(edgeIt); goNext(edgeIt))
+        edges.push_back(edgeIt);
+
+    // sort edges with respect to their weight, start with the highest
+    std::sort(edges.begin(), edges.end(), [] (auto a, auto b) { return getCargo(*a) >= getCargo(*b); });
+
+    TCargo maxWeight{};
+
+    if (BLOCKSIZE == 1)
+    {
+        for (std::size_t idx = 0u; idx < length(edges); ++idx)
+        {
+            auto const & edge = *edges[idx];
+            if (!conflictFree[edge->data_id])  // skip edge if conflict with a previous edge
+                continue;
+
+            maxWeight += getCargo(edge);  // edge is contained in the matching
+
+            // mark all adjacent edges
+            TVertexDescr const & src = getSource(edge);
+            for (TAdjacIterator ai(graph, src); !atEnd(ai); goNext(ai))
+            {
+                TEdgeDescr rmEdge = findEdge(graph, src, *ai);
+                conflictFree[rmEdge->data_id] = false;
+            }
+
+            TVertexDescr const & trg = getTarget(edge);
+            for (TAdjacIterator ai(graph, trg); !atEnd(ai); goNext(ai))
+            {
+                TEdgeDescr rmEdge = findEdge(graph, trg, *ai);
+                conflictFree[rmEdge->data_id] = false;
+            }
+
+            SEQAN_ASSERT(!conflictFree[edge->data_id]);
+        }
+    }
+    else
+    {
+        static_assert(BLOCKSIZE <= 32u, "BLOCKSIZE is only supported for values lower or equal 32.");
+        uint32_t isUsed;
+        std::array<TCargo, BLOCKSIZE> weights;
+        std::vector<std::size_t> selection;
+        selection.reserve(BLOCKSIZE);
+        std::size_t idx = 0u;
+
+        while (idx < length(edges))
+        {
+            for (selection.clear(); selection.size() < BLOCKSIZE && idx < length(edges); ++idx)
+            {
+                if (conflictFree[(*edges[idx])->data_id])
+                {
+                    weights[selection.size()] = getCargo(*edges[idx]);
+                    selection.push_back(idx);
+                }
+            }
+
+            // find conflicts
+            isUsed = 0xffffffff;
+            TConflictVect conflicts;
+            for (unsigned long i = 0u; i < selection.size(); ++i)
+            {
+                TVertexDescr const & src = getSource(*edges[selection[i]]);
+                TVertexDescr const & trg = getTarget(*edges[selection[i]]);
+                for (unsigned long j = i + 1u; j < selection.size(); ++j)
+                {
+                    if (src == getSource(*edges[selection[j]]) || trg == getSource(*edges[selection[j]]) ||
+                        src == getTarget(*edges[selection[j]]) || trg == getTarget(*edges[selection[j]]))
+                    {
+                        conflicts.push_back(std::make_pair(i, j));
+                    }
+                }
+            }
+
+            if (!conflicts.empty())
+                _evaluateConflicts<BLOCKSIZE, TCargo>(isUsed, weights, conflicts);
+
+            for (std::size_t i = 0u; i < selection.size(); ++i)
+            {
+                if (isUsed & (1 << i))  // i-th selection is in the MWM
+                {
+                    maxWeight += getCargo(*edges[selection[i]]);
+
+                    // mark all adjacent edges
+                    TVertexDescr const &src = getSource(*edges[selection[i]]);
+                    for (TAdjacIterator ai(graph, src); !atEnd(ai); goNext(ai))
+                        conflictFree[findEdge(graph, src, *ai)->data_id] = false;
+
+                    TVertexDescr const &trg = getTarget(*edges[selection[i]]);
+                    for (TAdjacIterator ai(graph, trg); !atEnd(ai); goNext(ai))
+                        conflictFree[findEdge(graph, trg, *ai)->data_id] = false;
+                }
+            }
+        }
+    }
+    return maxWeight;
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_GRAPH_ALGORITHMS_MAXIMUM_WEIGHTED_MATCHING_H_
diff --git a/include/seqan/index/index_bifm_stree.h b/include/seqan/index/index_bifm_stree.h
index 089f70d..6984c17 100644
--- a/include/seqan/index/index_bifm_stree.h
+++ b/include/seqan/index/index_bifm_stree.h
@@ -86,6 +86,9 @@ _goDownString(Iter<Index<TText, BidirectionalIndex<FMIndex<TOccSpec, TIndexSpec>
     TStringIter stringIt = begin(string, Standard());
     TStringIter stringEnd = end(string, Standard());
 
+    if (SEQAN_UNLIKELY(stringIt == stringEnd))
+        return true;
+
     _historyPush(_iter(it, TDirection()));
 
     for (lcp = 0; stringIt != stringEnd; ++stringIt, ++lcp)
diff --git a/include/seqan/index/index_fm_rank_dictionary_levels.h b/include/seqan/index/index_fm_rank_dictionary_levels.h
index f3ea16f..2eeeadd 100644
--- a/include/seqan/index/index_fm_rank_dictionary_levels.h
+++ b/include/seqan/index/index_fm_rank_dictionary_levels.h
@@ -190,16 +190,6 @@ struct RankDictionaryBitsPerBlock_<TValue, Levels<TSpec, TConfig> > :
     BitsPerValue<typename RankDictionaryBlock_<TValue, Levels<TSpec, TConfig> >::Type> {};
 
 // ----------------------------------------------------------------------------
-// Metafunction Size
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TSpec, typename TConfig>
-struct Size<RankDictionary<TValue, Levels<TSpec, TConfig> > >
-{
-    typedef typename Size<TConfig>::Type Type;
-};
-
-// ----------------------------------------------------------------------------
 // Metafunction RankDictionaryBlockSize_
 // ----------------------------------------------------------------------------
 
diff --git a/include/seqan/index/index_fm_stree.h b/include/seqan/index/index_fm_stree.h
index 956c17f..f17a732 100644
--- a/include/seqan/index/index_fm_stree.h
+++ b/include/seqan/index/index_fm_stree.h
@@ -56,18 +56,16 @@ struct HistoryStackFM_
     TSize       repLen;
     TAlphabet   lastChar;
 
-   
     HistoryStackFM_() {}
 
     template <typename TSize_, typename TAlphabet_>
-   
+
     HistoryStackFM_(Pair<TSize_> const &_range, TSize_ _repLen, TAlphabet_ _lastChar):
         range(_range),
         repLen(_repLen),
         lastChar(_lastChar)
     {}
 
-   
     HistoryStackFM_ const &
     operator=(HistoryStackFM_ const & _origin)
     {
@@ -90,7 +88,6 @@ struct VertexFM
     TSize       repLen;
     TAlphabet   lastChar;
 
-   
     VertexFM() :
         range(0, 0),
         smaller(0),
@@ -98,7 +95,6 @@ struct VertexFM
         lastChar(0)
     {}
 
-   
     VertexFM(MinimalCtor) :
         range(0, 0),
         smaller(0),
@@ -106,7 +102,6 @@ struct VertexFM
         lastChar(0)
     {}
 
-   
     VertexFM(Pair<TSize> newCurrentRange, TSize newSmallerValue, TSize newRepLen, TAlphabet newChar) :
         range(newCurrentRange),
         smaller(newSmallerValue),
@@ -114,7 +109,6 @@ struct VertexFM
         lastChar(newChar)
     {}
 
-   
     VertexFM(VertexFM const & other) :
         range(other.range),
         smaller(other.smaller),
@@ -359,11 +353,14 @@ _goDownString(Iter<Index<TText, FMIndex<TOccSpec, TIndexSpec> >, VSTree<TopDown<
     typedef Pair<TSize2>                                        TRange;
     typedef typename Iterator<TString const, Standard>::Type    TStringIter;
 
-    _historyPush(it);
-
     TStringIter stringIt = begin(string, Standard());
     TStringIter stringEnd = end(string, Standard());
 
+    if (SEQAN_UNLIKELY(stringIt == stringEnd))
+        return true;
+
+    _historyPush(it);
+
     for (lcp = 0; stringIt != stringEnd; ++stringIt, ++lcp)
     {
         TRange _range;
@@ -466,7 +463,7 @@ nodeUp(Iter<Index<TText, FMIndex<TOccSpec, TIndexSpec> >, VSTree< TopDown< Paren
     typedef typename VertexDescriptor<TIndex>::Type         TVertexDescriptor;
 
     if (!empty(it.history))
-        return TVertexDescriptor(back(it.history).range, back(it.history).repLen, back(it.history).lastChar);
+        return TVertexDescriptor(back(it.history).range, 0, back(it.history).repLen, back(it.history).lastChar);
     else
         return value(it);
 }
diff --git a/include/seqan/index/index_sa_stree.h b/include/seqan/index/index_sa_stree.h
index 580d4aa..80956e9 100644
--- a/include/seqan/index/index_sa_stree.h
+++ b/include/seqan/index/index_sa_stree.h
@@ -543,15 +543,15 @@ inline bool _goDownString(Iter<Index<TText, IndexSa<TIndexSpec> >, VSTree<TopDow
     typedef typename Iterator<TSA const, Standard>::Type    TSAIterator;
     typedef SearchTreeIterator<TSA const, SortedList>       TSearchTreeIterator;
 
-    // Save vertex descriptor.
-    _historyPush(it);
-
 #ifdef SEQAN_DEBUG
     std::cout << "parent: " << value(it).range << std::endl;
 #endif
 
     if (!empty(pattern))
     {
+        // Save vertex descriptor.
+        _historyPush(it);
+
         TIndex const & index = container(it);
         TSA const & sa = indexSA(index);
         TText const & text = indexText(index);
diff --git a/include/seqan/journaled_string_tree/journaled_string_tree_traverser.h b/include/seqan/journaled_string_tree/journaled_string_tree_traverser.h
index bf66e21..2dbf319 100644
--- a/include/seqan/journaled_string_tree/journaled_string_tree_traverser.h
+++ b/include/seqan/journaled_string_tree/journaled_string_tree_traverser.h
@@ -518,6 +518,18 @@ atEnd(TraverserImpl<TJst, JstTraversalSpec<TSpec> > & me)
     return length(*me._stackPtr) == 1 && back(*me._stackPtr).curEdgeIt == sourceEnd(impl::buffer(me));
 }
 
+// ----------------------------------------------------------------------------
+// Function isBase();
+// ----------------------------------------------------------------------------
+
+template <typename TJst, typename TSpec>
+inline bool
+isBase(TraverserImpl<TJst, JstTraversalSpec<TSpec> > const & me)
+{
+    SEQAN_ASSERT(me._stackPtr != nullptr);
+    return length(*me._stackPtr) == 1;
+}
+
 }  // namespace seqan
 
 #endif  // #ifndef INCLUDE_SEQAN_JOURNALED_STRING_TREE_JOURNALED_STRING_TREE_TRAVERSER_H_
diff --git a/include/seqan/platform.h b/include/seqan/platform.h
index 0e94bf6..774549a 100644
--- a/include/seqan/platform.h
+++ b/include/seqan/platform.h
@@ -322,7 +322,9 @@ typedef int8_t __int8;     // nolint
 
 // The symbols SEQAN_IS_64_BIT and SEQAN_IS_32_BIT can be used to check
 // whether we are on a 32 bit or on a 64 bit machine.
-#if defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__) || defined(__ia64__) || defined(__ppc64__) || defined(_WIN64)
+#if defined(__amd64__) || defined(__x86_64__) || defined(__aarch64__) || defined(__arch64__) || \
+    defined(__ia64__) || defined(__ppc64__) || defined(__PPC64__) || defined(_WIN64) || \
+    defined(__LP64__) || defined(_LP64)
 #define SEQAN_IS_64_BIT 1
 #define SEQAN_IS_32_BIT 0
 #else
@@ -462,4 +464,65 @@ typedef int8_t __int8;     // nolint
 #undef COMPILER_VERSION
 #endif
 
-#endif
+// BYTE-ORDER DETECTION (default is little-endian)
+#ifndef SEQAN_BIG_ENDIAN
+    #ifdef __GLIBC__
+        #include <endian.h>
+    #endif
+
+    #if defined(__FreeBSD__) || (defined(__has_include) && __has_include(<sys/endian.h>))
+        #include <sys/endian.h>
+    #endif
+
+    #if (defined( _BYTE_ORDER  ) && ( _BYTE_ORDER   ==        _BIG_ENDIAN  )) || \
+        (defined(__BYTE_ORDER  ) && (__BYTE_ORDER   ==       __BIG_ENDIAN  )) || \
+        (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || \
+                                                     defined(__BIG_ENDIAN__)
+        #define SEQAN_BIG_ENDIAN 1
+    #else
+        #define SEQAN_BIG_ENDIAN 0
+    #endif
+#endif // SEQAN_BIG_ENDIAN
+
+template <typename T>
+constexpr void ensure_little_endian(T &)
+{}
+
+#if SEQAN_BIG_ENDIAN
+inline void ensure_little_endian(int16_t & in)
+{
+    in = htole16(in);
+}
+inline void ensure_little_endian(uint16_t & in)
+{
+    in = htole16(in);
+}
+inline void ensure_little_endian(int32_t & in)
+{
+    in = htole32(in);
+}
+inline void ensure_little_endian(uint32_t & in)
+{
+    in = htole32(in);
+}
+inline void ensure_little_endian(int64_t & in)
+{
+    in = htole64(in);
+}
+inline void ensure_little_endian(uint64_t & in)
+{
+    in = htole64(in);
+}
+inline void ensure_little_endian(float & in)
+{
+    in = reinterpret_cast<float>(htole32(reinterpret_cast<uint32_t>(in)));
+}
+inline void ensure_little_endian(double & in)
+{
+    in = reinterpret_cast<double>(htole64(reinterpret_cast<uint64_t>(in)));
+}
+//TODO long double
+
+#endif // SEQAN_BIG_ENDIAN
+
+#endif // HEADER GUARD
diff --git a/include/seqan/reduced_aminoacid.h b/include/seqan/reduced_aminoacid.h
index 782b078..fc3fc97 100644
--- a/include/seqan/reduced_aminoacid.h
+++ b/include/seqan/reduced_aminoacid.h
@@ -1,7 +1,7 @@
 // ==========================================================================
 //                 SeqAn - The Library for Sequence Analysis
 // ==========================================================================
-// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -42,9 +42,24 @@
 
 #include <seqan/reduced_aminoacid/reduced_aminoacid_base.h>
 
+#include <seqan/reduced_aminoacid/reduced_aminoacid_buchfink11_base.h>
+#include <seqan/reduced_aminoacid/reduced_aminoacid_buchfink11_tables.h>
+
+#include <seqan/reduced_aminoacid/reduced_aminoacid_cannata10_base.h>
+#include <seqan/reduced_aminoacid/reduced_aminoacid_cannata10_tables.h>
+
+#include <seqan/reduced_aminoacid/reduced_aminoacid_li10_base.h>
+#include <seqan/reduced_aminoacid/reduced_aminoacid_li10_tables.h>
+
+#include <seqan/reduced_aminoacid/reduced_aminoacid_murphy5_base.h>
+#include <seqan/reduced_aminoacid/reduced_aminoacid_murphy5_tables.h>
+
 #include <seqan/reduced_aminoacid/reduced_aminoacid_murphy10_base.h>
 #include <seqan/reduced_aminoacid/reduced_aminoacid_murphy10_tables.h>
 
+#include <seqan/reduced_aminoacid/reduced_aminoacid_solis10_base.h>
+#include <seqan/reduced_aminoacid/reduced_aminoacid_solis10_tables.h>
+
 // #include <seqan/reduced_aminoacid/reduced_aminoacid_cluster_red_base.h>
 // #include <seqan/reduced_aminoacid/reduced_aminoacid_cluster_red_tables_20_to_n_b62.h>
 // #include <seqan/reduced_aminoacid/reduced_aminoacid_cluster_red_tables_22_to_n_b62.h>
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_buchfink11_base.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_buchfink11_base.h
new file mode 100644
index 0000000..ac4c51c
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_buchfink11_base.h
@@ -0,0 +1,123 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Buchfink11 reduction of AminoAcid alphabet
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_BUCHFINK11_BASE_H_
+#define SEQAN_REDUCED_AMINOACID_BUCHFINK11_BASE_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Tag Buchfink11
+// -----------------------------------------------------------------------
+
+/*!
+ * @tag Buchfink11
+ * @brief Specialization for @link ReducedAminoAcid @endlink#
+ * @headerfile seqan/reduced_aminoacid.h
+ *
+ * @signature typedef Buchfink11 Tag<Buchfink11_>;
+ *
+ * This is the 11-character reduction defined by Buchfink et al,
+ * 2014, <a href="https://www.ncbi.nlm.nih.gov/pubmed/25402007">https://www.ncbi.nlm.nih.gov/pubmed/25402007</a>
+ *
+ * This alphabet is used by tool Diamond.
+ *
+ * Since it was created from the 20-letter alphabet the clusters in SeqAn are
+ * not identical (they contain more symbols). This is the clustering:
+ * @code{.txt}
+ *   'A', // A S T X
+ *   'B', // B D E K N O Q R Z
+ *   'C', // C U
+ *   'F', // F *
+ *   'G', // G
+ *   'H', // H
+ *   'I', // I J L V
+ *   'M', // M
+ *   'P', // P
+ *   'W', // W
+ *   'Y'  // Y
+ * @endcode
+ *
+ */
+
+struct Buchfink11_ {};
+
+typedef Tag<Buchfink11_> Buchfink11;
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Metafunction ValueSize
+// -----------------------------------------------------------------------
+
+template <>
+struct ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Buchfink11> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 11;
+};
+
+// -----------------------------------------------------------------------
+// Metafunction BitPerValue
+// -----------------------------------------------------------------------
+
+template <>
+struct BitsPerValue<SimpleType<unsigned char, ReducedAminoAcid_<Buchfink11> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 4;
+};
+
+// -----------------------------------------------------------------------
+// Translation Tables (implementations see extra files)
+// -----------------------------------------------------------------------
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+}
+#endif // def SEQAN_REDUCED_AMINOACID_BUCHFINK11_BASE_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_buchfink11_tables.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_buchfink11_tables.h
new file mode 100644
index 0000000..b7f0ccb
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_buchfink11_tables.h
@@ -0,0 +1,155 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Buchfink11 reduction tables
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_BUCHFINK11_TABLES_H_
+#define SEQAN_REDUCED_AMINOACID_BUCHFINK11_TABLES_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template <typename TSpec>
+struct TranslateTableRedAAToChar_<Buchfink11, TSpec>
+{
+    static const char VALUE[ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Buchfink11> > >::VALUE];
+};
+
+template <typename TSpec>
+struct TranslateTableCharToRedAA_<Buchfink11, TSpec>
+{
+    static const char VALUE[256];
+};
+
+template <typename TSpec>
+struct TranslateTableAAToRedAA_<Buchfink11, TSpec>
+{
+    static const char VALUE[27];
+};
+
+template <typename TSpec>
+struct TranslateTableByteToRedAA_<Buchfink11, TSpec>
+{
+    static const char VALUE[256];
+};
+
+// ---------------------------------- N = 11 ------------------------------
+
+template <typename TVoidSpec>
+char const TranslateTableRedAAToChar_<Buchfink11, TVoidSpec>::VALUE[11] =
+{
+    'A', // A S T X
+    'B', // B D E K N O Q R Z
+    'C', // C U
+    'F', // F *
+    'G', // G
+    'H', // H
+    'I', // I J L V
+    'M', // M
+    'P', // P
+    'W', // W
+    'Y'  // Y
+};
+
+template <typename TVoidSpec>
+char const TranslateTableCharToRedAA_<Buchfink11, TVoidSpec>::VALUE[256] =
+{
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  1,  2,  1,  1,  3,  4,  5,  6,  6,
+     1,  6,  7,  1,  1,  8,  1,  1,  0,  0,  2,  6,  9,  0, 10,
+     1,  0,  0,  0,  0,  0,  0,  0,  1,  2,  1,  1,  3,  4,  5,
+     6,  6,  1,  6,  7,  1,  1,  8,  1,  1,  0,  0,  2,  6,  9,
+     0, 10,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+template <typename TVoidSpec>
+char const TranslateTableAAToRedAA_<Buchfink11, TVoidSpec>::VALUE[27] =
+{
+     0,  1,  2,  1,  1,  3,  4,  5,  6,  6,  1,  6,  7,
+     1,  1,  8,  1,  1,  0,  0,  2,  6,  9,  10, 1,  0,  3
+};
+
+template <typename TVoidSpec>
+char const TranslateTableByteToRedAA_<Buchfink11, TVoidSpec>::VALUE[256] =
+{
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+} // namespace
+
+#endif // SEQAN_REDUCED_AMINOACID_BUCHFINK11_TABLES_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_cannata10_base.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_cannata10_base.h
new file mode 100644
index 0000000..cc3dc71
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_cannata10_base.h
@@ -0,0 +1,120 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Cannata10 reduction of AminoAcid alphabet
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_CANNATA10_BASE_H_
+#define SEQAN_REDUCED_AMINOACID_CANNATA10_BASE_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Tag Cannata10
+// -----------------------------------------------------------------------
+
+/*!
+ * @tag Cannata10
+ * @brief Specialization for @link ReducedAminoAcid @endlink#
+ * @headerfile seqan/reduced_aminoacid.h
+ *
+ * @signature typedef Cannata10 Tag<Cannata10_>;
+ *
+ * This is the 10-character reduction defined by Cannata et al,
+ * 2002, <a href="https://www.ncbi.nlm.nih.gov/pubmed/12176833">https://www.ncbi.nlm.nih.gov/pubmed/12176833</a>
+ *
+ * Since it was created from the 20-letter alphabet the clusters in SeqAn are
+ * not identical (they contain more symbols). This is the clustering:
+ * @code{.txt}
+ *   'A', // A G S T X
+ *   'B', // B D N
+ *   'C', // C U
+ *   'E', // E Q Z
+ *   'F', // F Y *
+ *   'H', // H
+ *   'I', // I J L M V
+ *   'K', // K O R
+ *   'P', // P
+ *   'W'  // W
+ * @endcode
+ *
+ */
+
+struct Cannata10_ {};
+
+typedef Tag<Cannata10_> Cannata10;
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Metafunction ValueSize
+// -----------------------------------------------------------------------
+
+template <>
+struct ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Cannata10> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 10;
+};
+
+// -----------------------------------------------------------------------
+// Metafunction BitPerValue
+// -----------------------------------------------------------------------
+
+template <>
+struct BitsPerValue<SimpleType<unsigned char, ReducedAminoAcid_<Cannata10> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 4;
+};
+
+// -----------------------------------------------------------------------
+// Translation Tables (implementations see extra files)
+// -----------------------------------------------------------------------
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+}
+#endif // def SEQAN_REDUCED_AMINOACID_CANNATA10_BASE_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_cannata10_tables.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_cannata10_tables.h
new file mode 100644
index 0000000..d614a2c
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_cannata10_tables.h
@@ -0,0 +1,154 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Cannata10 reduction tables
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_CANNATA10_TABLES_H_
+#define SEQAN_REDUCED_AMINOACID_CANNATA10_TABLES_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template <typename TSpec>
+struct TranslateTableRedAAToChar_<Cannata10, TSpec>
+{
+    static const char VALUE[ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Cannata10> > >::VALUE];
+};
+
+template <typename TSpec>
+struct TranslateTableCharToRedAA_<Cannata10, TSpec>
+{
+    static const char VALUE[256];
+};
+
+template <typename TSpec>
+struct TranslateTableAAToRedAA_<Cannata10, TSpec>
+{
+    static const char VALUE[27];
+};
+
+template <typename TSpec>
+struct TranslateTableByteToRedAA_<Cannata10, TSpec>
+{
+    static const char VALUE[256];
+};
+
+// ---------------------------------- N = 10 ------------------------------
+
+template <typename TVoidSpec>
+char const TranslateTableRedAAToChar_<Cannata10, TVoidSpec>::VALUE[10] =
+{
+    'A', // A G S T X
+    'B', // B D N
+    'C', // C U
+    'E', // E Q Z
+    'F', // F Y *
+    'H', // H
+    'I', // I J L M V
+    'K', // K O R
+    'P', // P
+    'W'  // W
+};
+
+template <typename TVoidSpec>
+char const TranslateTableCharToRedAA_<Cannata10, TVoidSpec>::VALUE[256] =
+{
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  1,  2,  1,  3,  4,  0,  5,  6,  6,
+     7,  6,  6,  1,  7,  8,  3,  7,  0,  0,  2,  6,  9,  0,  4,
+     3,  0,  0,  0,  0,  0,  0,  0,  1,  2,  1,  3,  4,  0,  5,
+     6,  6,  7,  6,  6,  1,  7,  8,  3,  7,  0,  0,  2,  6,  9,
+     0,  4,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+template <typename TVoidSpec>
+char const TranslateTableAAToRedAA_<Cannata10, TVoidSpec>::VALUE[27] =
+{
+     0,  1,  2,  1,  3,  4,  0,  5,  6,  6,  7,  6,  6,
+     1,  7,  8,  3,  7,  0,  0,  2,  6,  9,  4,  3,  0,  4
+};
+
+template <typename TVoidSpec>
+char const TranslateTableByteToRedAA_<Cannata10, TVoidSpec>::VALUE[256] =
+{
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+} // namespace
+
+#endif // SEQAN_REDUCED_AMINOACID_CANNATA10_TABLES_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_li10_base.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_li10_base.h
new file mode 100644
index 0000000..0b0a039
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_li10_base.h
@@ -0,0 +1,120 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Li10 reduction of AminoAcid alphabet
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_LI10_BASE_H_
+#define SEQAN_REDUCED_AMINOACID_LI10_BASE_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Tag Li10
+// -----------------------------------------------------------------------
+
+/*!
+ * @tag Li10
+ * @brief Specialization for @link ReducedAminoAcid @endlink#
+ * @headerfile seqan/reduced_aminoacid.h
+ *
+ * @signature typedef Li10 Tag<Li10_>;
+ *
+ * This is the 10-character reduction defined by Li et al,
+ * 2003, <a href="https://www.ncbi.nlm.nih.gov/pubmed/12826723">https://www.ncbi.nlm.nih.gov/pubmed/12826723</a>
+ *
+ * Since it was created from the 20-letter alphabet the clusters in SeqAn are
+ * not identical (they contain more symbols). This is the clustering:
+ * @code{.txt}
+ *   'A', // A S T X
+ *   'B', // B D E Q Z
+ *   'C', // C U
+ *   'F', // F W Y *
+ *   'G', // G
+ *   'H', // H N
+ *   'I', // I V
+ *   'J', // J L M
+ *   'K', // K O R
+ *   'P', // P
+ * @endcode
+ *
+ */
+
+struct Li10_ {};
+
+typedef Tag<Li10_> Li10;
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Metafunction ValueSize
+// -----------------------------------------------------------------------
+
+template <>
+struct ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Li10> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 10;
+};
+
+// -----------------------------------------------------------------------
+// Metafunction BitPerValue
+// -----------------------------------------------------------------------
+
+template <>
+struct BitsPerValue<SimpleType<unsigned char, ReducedAminoAcid_<Li10> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 4;
+};
+
+// -----------------------------------------------------------------------
+// Translation Tables (implementations see extra files)
+// -----------------------------------------------------------------------
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+}
+#endif // def SEQAN_REDUCED_AMINOACID_LI10_BASE_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_li10_tables.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_li10_tables.h
new file mode 100644
index 0000000..3fb1796
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_li10_tables.h
@@ -0,0 +1,154 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Li10 reduction tables
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_LI10_TABLES_H_
+#define SEQAN_REDUCED_AMINOACID_LI10_TABLES_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template <typename TSpec>
+struct TranslateTableRedAAToChar_<Li10, TSpec>
+{
+    static const char VALUE[ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Li10> > >::VALUE];
+};
+
+template <typename TSpec>
+struct TranslateTableCharToRedAA_<Li10, TSpec>
+{
+    static const char VALUE[256];
+};
+
+template <typename TSpec>
+struct TranslateTableAAToRedAA_<Li10, TSpec>
+{
+    static const char VALUE[27];
+};
+
+template <typename TSpec>
+struct TranslateTableByteToRedAA_<Li10, TSpec>
+{
+    static const char VALUE[256];
+};
+
+// ---------------------------------- N = 10 ------------------------------
+
+template <typename TVoidSpec>
+char const TranslateTableRedAAToChar_<Li10, TVoidSpec>::VALUE[10] =
+{
+    'A', // A S T X
+    'B', // B D E Q Z
+    'C', // C U
+    'F', // F W Y *
+    'G', // G
+    'H', // H N
+    'I', // I V
+    'J', // J L M
+    'K', // K O R
+    'P', // P
+};
+
+template <typename TVoidSpec>
+char const TranslateTableCharToRedAA_<Li10, TVoidSpec>::VALUE[256] =
+{
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  1,  2,  1,  1,  3,  4,  5,  6,  7,
+     8,  7,  7,  5,  8,  9,  1,  8,  0,  0,  2,  6,  3,  0,  3,
+     1,  0,  0,  0,  0,  0,  0,  0,  1,  2,  1,  1,  3,  4,  5,
+     6,  7,  8,  7,  7,  5,  8,  9,  1,  8,  0,  0,  2,  6,  3,
+     0,  3,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+template <typename TVoidSpec>
+char const TranslateTableAAToRedAA_<Li10, TVoidSpec>::VALUE[27] =
+{
+     0,  1,  2,  1,  1,  3,  4,  5,  6,  7,  8,  7,  7,
+     5,  8,  9,  1,  8,  0,  0,  2,  6,  3,  3,  1,  0, 3
+};
+
+template <typename TVoidSpec>
+char const TranslateTableByteToRedAA_<Li10, TVoidSpec>::VALUE[256] =
+{
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+} // namespace
+
+#endif // SEQAN_REDUCED_AMINOACID_LI10_TABLES_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_murphy5_base.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_murphy5_base.h
new file mode 100644
index 0000000..74e3a1f
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_murphy5_base.h
@@ -0,0 +1,115 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Wang5 reduction of AminoAcid alphabet
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_MURPHY5_BASE_H_
+#define SEQAN_REDUCED_AMINOACID_MURPHY5_BASE_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Tag Murphy5
+// -----------------------------------------------------------------------
+
+/*!
+ * @tag Murphy5
+ * @brief Specialization for @link ReducedAminoAcid @endlink#
+ * @headerfile seqan/reduced_aminoacid.h
+ *
+ * @signature typedef Murphy5 Tag<Murphy5_>;
+ *
+ * This is the 5-character reduction defined by Murphy et al,
+ * 2000, <a href="http://www.ncbi.nlm.nih.gov/pubmed/10775656">http://www.ncbi.nlm.nih.gov/pubmed/10775656</a>
+ *
+ * Since it was created from the 20-letter alphabet the clusters in SeqAn are
+ * not identical (they contain more symbols). This is the clustering:
+ * @code{.txt}
+ *   'A', // A G P S T X
+ *   'B', // B D E N Q Z
+ *   'C', // C I J L M U V
+ *   'F', // F W Y *
+ *   'K', // H K O R
+ * @endcode
+ *
+ */
+
+struct Murphy5_ {};
+
+typedef Tag<Murphy5_> Murphy5;
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Metafunction ValueSize
+// -----------------------------------------------------------------------
+
+template <>
+struct ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Murphy5> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 5;
+};
+
+// -----------------------------------------------------------------------
+// Metafunction BitPerValue
+// -----------------------------------------------------------------------
+
+template <>
+struct BitsPerValue<SimpleType<unsigned char, ReducedAminoAcid_<Murphy5> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 3;
+};
+
+// -----------------------------------------------------------------------
+// Translation Tables (implementations see extra files)
+// -----------------------------------------------------------------------
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+}
+#endif // def SEQAN_REDUCED_AMINOACID_MURPHY5_BASE_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_murphy5_tables.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_murphy5_tables.h
new file mode 100644
index 0000000..9307786
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_murphy5_tables.h
@@ -0,0 +1,149 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Murphy5 reduction tables
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_MURPHY5_TABLES_H_
+#define SEQAN_REDUCED_AMINOACID_MURPHY5_TABLES_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template <typename TSpec>
+struct TranslateTableRedAAToChar_<Murphy5, TSpec>
+{
+    static const char VALUE[ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Murphy5> > >::VALUE];
+};
+
+template <typename TSpec>
+struct TranslateTableCharToRedAA_<Murphy5, TSpec>
+{
+    static const char VALUE[256];
+};
+
+template <typename TSpec>
+struct TranslateTableAAToRedAA_<Murphy5, TSpec>
+{
+    static const char VALUE[27];
+};
+
+template <typename TSpec>
+struct TranslateTableByteToRedAA_<Murphy5, TSpec>
+{
+    static const char VALUE[256];
+};
+
+// ---------------------------------- N = 5 ------------------------------
+
+template <typename TVoidSpec>
+char const TranslateTableRedAAToChar_<Murphy5, TVoidSpec>::VALUE[5] =
+{
+    'A', // A G P S T X 
+    'B', // B D E N Q Z
+    'C', // C I J L M U V
+    'F', // F W Y *
+    'H', // H K O R
+};
+
+template <typename TVoidSpec>
+char const TranslateTableCharToRedAA_<Murphy5, TVoidSpec>::VALUE[256] =
+{
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  1,  2,  1,  1,  3,  0,  4,  2,  2,
+     4,  2,  2,  1,  4,  0,  1,  4,  0,  0,  2,  2,  3,  0,  3,
+     1,  0,  0,  0,  0,  0,  0,  0,  1,  2,  1,  1,  3,  0,  4,
+     2,  2,  4,  2,  2,  1,  4,  0,  1,  4,  0,  0,  2,  2,  3,
+     0,  3,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+template <typename TVoidSpec>
+char const TranslateTableAAToRedAA_<Murphy5, TVoidSpec>::VALUE[27] =
+{
+     0,  1,  2,  1,  1,  3,  0,  4,  2,  2,  4,  2,  2,
+     1,  4,  0,  1,  4,  0,  0,  2,  2,  3,  3,  1,  0,  3
+};
+
+template <typename TVoidSpec>
+char const TranslateTableByteToRedAA_<Murphy5, TVoidSpec>::VALUE[256] =
+{
+     0,  1,  2,  3,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+} // namespace
+
+#endif // SEQAN_REDUCED_AMINOACID_MURPHY5_TABLES_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_solis10_base.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_solis10_base.h
new file mode 100644
index 0000000..aa28c8e
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_solis10_base.h
@@ -0,0 +1,120 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Solis10 reduction of AminoAcid alphabet
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_SOLIS10_BASE_H_
+#define SEQAN_REDUCED_AMINOACID_SOLIS10_BASE_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Tag Solis10
+// -----------------------------------------------------------------------
+
+/*!
+ * @tag Solis10
+ * @brief Specialization for @link ReducedAminoAcid @endlink#
+ * @headerfile seqan/reduced_aminoacid.h
+ *
+ * @signature typedef Solis10 Tag<Solis10_>;
+ *
+ * This is the 10-character reduction defined by Solis,
+ * 2015, <a href="hhttps://www.ncbi.nlm.nih.gov/pubmed/26407535">https://www.ncbi.nlm.nih.gov/pubmed/26407535</a>
+ *
+ * Since it was created from the 20-letter alphabet the clusters in SeqAn are
+ * not identical (they contain more symbols). This is the clustering:
+ * @code{.txt}
+ *   'A', // A X
+ *   'B', // B D E Z
+ *   'C', // C U
+ *   'F', // F *
+ *   'G', // G N Q S
+ *   'H', // H O R
+ *   'I', // I J L M V
+ *   'K', // K
+ *   'P', // P T
+ *   'W'  // W Y
+ * @endcode
+ *
+ */
+
+struct Solis10_ {};
+
+typedef Tag<Solis10_> Solis10;
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// -----------------------------------------------------------------------
+// Metafunction ValueSize
+// -----------------------------------------------------------------------
+
+template <>
+struct ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Solis10> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 10;
+};
+
+// -----------------------------------------------------------------------
+// Metafunction BitPerValue
+// -----------------------------------------------------------------------
+
+template <>
+struct BitsPerValue<SimpleType<unsigned char, ReducedAminoAcid_<Solis10> > >
+{
+    typedef uint8_t Type;
+    static const Type VALUE = 4;
+};
+
+// -----------------------------------------------------------------------
+// Translation Tables (implementations see extra files)
+// -----------------------------------------------------------------------
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+}
+#endif // def SEQAN_REDUCED_AMINOACID_SOLIS10_BASE_H_
diff --git a/include/seqan/reduced_aminoacid/reduced_aminoacid_solis10_tables.h b/include/seqan/reduced_aminoacid/reduced_aminoacid_solis10_tables.h
new file mode 100644
index 0000000..1f02718
--- /dev/null
+++ b/include/seqan/reduced_aminoacid/reduced_aminoacid_solis10_tables.h
@@ -0,0 +1,154 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2017, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Kristin Knorr <kristin.knorr at fu-berlin.de>
+// ==========================================================================
+// Solis10 reduction tables
+// ==========================================================================
+
+#ifndef SEQAN_REDUCED_AMINOACID_SOLIS10_TABLES_H_
+#define SEQAN_REDUCED_AMINOACID_SOLIS10_TABLES_H_
+
+namespace seqan {
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template <typename TSpec>
+struct TranslateTableRedAAToChar_<Solis10, TSpec>
+{
+    static const char VALUE[ValueSize<SimpleType<unsigned char, ReducedAminoAcid_<Solis10> > >::VALUE];
+};
+
+template <typename TSpec>
+struct TranslateTableCharToRedAA_<Solis10, TSpec>
+{
+    static const char VALUE[256];
+};
+
+template <typename TSpec>
+struct TranslateTableAAToRedAA_<Solis10, TSpec>
+{
+    static const char VALUE[27];
+};
+
+template <typename TSpec>
+struct TranslateTableByteToRedAA_<Solis10, TSpec>
+{
+    static const char VALUE[256];
+};
+
+// ---------------------------------- N = 10 ------------------------------
+
+template <typename TVoidSpec>
+char const TranslateTableRedAAToChar_<Solis10, TVoidSpec>::VALUE[10] =
+{
+    'A', // A X
+    'B', // B D E Z
+    'C', // C U
+    'F', // F *
+    'G', // G N Q S
+    'H', // H O R
+    'I', // I J L M V
+    'K', // K
+    'P', // P T
+    'W'  // W Y
+};
+
+template <typename TVoidSpec>
+char const TranslateTableCharToRedAA_<Solis10, TVoidSpec>::VALUE[256] =
+{
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  1,  2,  1,  1,  3,  4,  5,  6,  6,
+     7,  6,  6,  4,  5,  8,  4,  5,  4,  8,  2,  6,  9,  0,  9,
+     1,  0,  0,  0,  0,  0,  0,  0,  1,  2,  1,  1,  3,  4,  5,
+     6,  6,  7,  6,  6,  4,  5,  8,  4,  5,  4,  8,  2,  6,  9,
+     0,  9,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+template <typename TVoidSpec>
+char const TranslateTableAAToRedAA_<Solis10, TVoidSpec>::VALUE[27] =
+{
+     0,  1,  2,  1,  1,  3,  4,  5,  6,  6,  7,  6,  6,
+     4,  5,  8,  4,  5,  4,  8,  2,  6,  9,  9,  1,  0,  3
+};
+
+template <typename TVoidSpec>
+char const TranslateTableByteToRedAA_<Solis10, TVoidSpec>::VALUE[256] =
+{
+     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+     0
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+} // namespace
+
+#endif // SEQAN_REDUCED_AMINOACID_SOLIS10_TABLES_H_
diff --git a/include/seqan/score.h b/include/seqan/score.h
index 44327ff..dfa4024 100644
--- a/include/seqan/score.h
+++ b/include/seqan/score.h
@@ -38,6 +38,7 @@
 #define SEQAN_SH_
 
 #include <seqan/basic.h>
+#include <seqan/simd.h>
 
 #include <seqan/stream.h>
 
diff --git a/include/seqan/score/score_simd_wrapper.h b/include/seqan/score/score_simd_wrapper.h
index 5bf95b4..f964d49 100644
--- a/include/seqan/score/score_simd_wrapper.h
+++ b/include/seqan/score/score_simd_wrapper.h
@@ -122,6 +122,10 @@ public:
 // Function score(); SimpleScore Wrapper
 // ----------------------------------------------------------------------------
 
+template <unsigned LENGTH>
+struct VectorLength_
+{};
+
 template <typename TValue, typename TScore, typename TSeqHVal, typename TSeqVVal>
 inline SEQAN_FUNC_DISABLE_IF(IsScoreMatrix_<TScore>, TValue)
 score(Score<TValue, ScoreSimdWrapper<TScore> > const & me, TSeqHVal const & valH, TSeqVVal const & valV)
@@ -133,49 +137,12 @@ score(Score<TValue, ScoreSimdWrapper<TScore> > const & me, TSeqHVal const & valH
 // Function score(); ScoreMatrix Wrapper
 // ----------------------------------------------------------------------------
 
-template <unsigned LENGTH>
-struct VectorLength_
-{};
-
-#define SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_2(t, d, pos)     d[t[1 + pos]], d[t[pos]]
-#define SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_4(t, d, pos)     SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_2(t, d, pos + 2), SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_2(t, d, pos)
-#define SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_8(t, d, pos)     SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_4(t, d, pos + 4), SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_4(t, d, pos)
-#define SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_16(t, d, pos)    SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_8(t, d, pos + 8), SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_8(t, d, pos)
-#define SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_32(t, d, pos)    SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_16(t, d, pos + 16), SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_16(t, d, pos)
-
-#define SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_DELEGATE(MACRO, t, d) MACRO(t, d, 0)
-#define SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL(t, d, SIZE) SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_DELEGATE(SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL_##SIZE, t, d)
-
-#define SEQAN_FIXED_VECTOR_FILL_IMPL(SIZE)                                        \
-template <typename TTarget, typename TPos, typename TData>                        \
-inline void                                                                       \
-_fixedSizeVectorFill(TTarget & target,                                            \
-                     TPos const & pos,                                            \
-                     TData const & data,                                          \
-                     VectorLength_<SIZE> const & /*scope*/)                       \
-{                                                                                 \
-    fillVector(target, SEQAN_FIXED_VECTOR_FILL_VALUE_IMPL(pos, data, SIZE));      \
-}
-
-SEQAN_FIXED_VECTOR_FILL_IMPL(2)
-SEQAN_FIXED_VECTOR_FILL_IMPL(4)
-SEQAN_FIXED_VECTOR_FILL_IMPL(8)
-SEQAN_FIXED_VECTOR_FILL_IMPL(16)
-SEQAN_FIXED_VECTOR_FILL_IMPL(32)
-
-// TODO(rrahn): We should make the fixedSizeVectorFill the fall back gather interface, if gather is not implemented.
 template <typename TValue, typename TScore, typename TVal1, typename TVal2>
 inline SEQAN_FUNC_ENABLE_IF(IsScoreMatrix_<TScore>, TValue)
 score(Score<TValue, ScoreSimdWrapper<TScore> > const & sc, TVal1 const & val1, TVal2 const & val2)
 {
     SEQAN_ASSERT(sc._baseScorePtr != nullptr);
-#ifdef __AVX2__
     return gather(&sc._baseScorePtr->data_tab[0], val1 + val2);
-#else
-    TValue results;
-    _fixedSizeVectorFill(results, val1 + val2, sc._baseScorePtr->data_tab, VectorLength_<LENGTH<TVal1>::VALUE>());
-    return results;
-#endif
 }
 
 }
diff --git a/include/seqan/simd.h b/include/seqan/simd.h
new file mode 100644
index 0000000..e61f20b
--- /dev/null
+++ b/include/seqan/simd.h
@@ -0,0 +1,124 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Marcel Ehrhardt <marcel.ehrhardt at fu-berlin.de>
+// ==========================================================================
+// generic SIMD interface for SSE3 / AVX2
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_SEQAN_SIMD_H_
+#define SEQAN_INCLUDE_SEQAN_SIMD_H_
+
+#include <seqan/basic.h>
+
+// Check if more than simd back end is selected
+#if SEQAN_SEQANSIMD_ENABLED && SEQAN_UMESIMD_ENABLED
+    #error UME::SIMD and SEQAN::SIMD are both enabled, you can only use one SIMD back end.
+#endif
+
+// MSVC doesn't define SSE4 macros, even if instruction set is available (e.g.
+// when AVX is defined)
+#if defined(COMPILER_MSVC) && defined(__AVX__) && !defined(__SSE4_1__) && !defined(__SSE4_2__)
+    #define __SSE4_1__ 1
+    #define __SSE4_2__ 1
+#endif
+
+// Define global macro to check if simd instructions are enabled.
+#if defined(__AVX512F__) || defined(__AVX2__) || (defined(__SSE4_1__) && defined(__SSE4_2__))
+    #define SEQAN_SIMD_ENABLED
+#else
+    #undef SEQAN_SIMD_ENABLED
+    #undef SEQAN_SEQANSIMD_ENABLED
+    #undef SEQAN_UMESIMD_ENABLED
+#endif
+
+// SIMD operations make only sense on modern 64bit architectures.
+#if SEQAN_IS_32_BIT
+    // TODO(marehr): If we switch to jenkins, filter out these warnings
+    #if !(defined(NDEBUG) || defined(SEQAN_ENABLE_TESTING))
+        #pragma message("SIMD acceleration is only available on 64bit systems")
+    #endif
+    #undef SEQAN_SIMD_ENABLED
+    #undef SEQAN_SEQANSIMD_ENABLED
+    #undef SEQAN_UMESIMD_ENABLED
+#endif // SEQAN_IS_32_BIT
+
+// Fallback to seqan's simd implementation if nothing was specified.
+#if defined(SEQAN_SIMD_ENABLED) && !defined(SEQAN_UMESIMD_ENABLED) && !defined(SEQAN_SEQANSIMD_ENABLED)
+    #define SEQAN_SEQANSIMD_ENABLED
+#endif
+
+// Seqan's simd implementation supports only avx2 and sse4.
+#if defined(SEQAN_SEQANSIMD_ENABLED) && !(defined(__AVX2__) || (defined(__SSE4_1__) && defined(__SSE4_2__)))
+    #undef SEQAN_SIMD_ENABLED
+    #undef SEQAN_SEQANSIMD_ENABLED
+#endif
+
+#if defined(SEQAN_SEQANSIMD_ENABLED) && (defined(COMPILER_MSVC) || defined(COMPILER_WINTEL))
+    #error SEQAN::SIMD (vector extension) is not supported by msvc and windows intel compiler, try compiling with -DSEQAN_UMESIMD_ENABLED
+#endif
+
+// Define maximal size of vector in byte.
+#if defined(SEQAN_SEQANSIMD_ENABLED) && defined(__AVX512F__)
+    // TODO(marehr): If we switch to jenkins, filter out these warnings
+    #if !(defined(NDEBUG) || defined(SEQAN_ENABLE_TESTING))
+        #pragma message("SEQAN_SIMD doesn't support AVX512, thus falling back to AVX2 " \
+                        "(we are using some back ported instruction for AVX2 which where introduced since AVX512)")
+    #endif
+    #define SEQAN_SIZEOF_MAX_VECTOR 32
+#elif defined(__AVX512F__)
+    #define SEQAN_SIZEOF_MAX_VECTOR 64
+#elif defined(__AVX2__)
+    #define SEQAN_SIZEOF_MAX_VECTOR 32
+#elif defined(__SSE4_1__) && defined(__SSE4_2__)
+    #define SEQAN_SIZEOF_MAX_VECTOR 16
+#endif
+
+#include "simd/simd_base.h"
+#include "simd/simd_base_seqan_impl.h"
+
+#if defined(SEQAN_SEQANSIMD_ENABLED)
+    #if defined(__SSE4_2__)
+    #include "simd/simd_base_seqan_impl_sse4.2.h"
+    #endif // defined(SEQAN_SSE4)
+
+    #if defined(__AVX2__)
+    #include "simd/simd_base_seqan_impl_avx2.h"
+    #endif // defined(__AVX2__)
+
+    #include "simd/simd_base_seqan_interface.h"
+#endif // defined(SEQAN_SEQANSIMD_ENABLED)
+
+#if defined(SEQAN_UMESIMD_ENABLED)
+    #include "simd/simd_base_umesimd_impl.h"
+#endif
+
+#endif // SEQAN_INCLUDE_SEQAN_SIMD_H_
diff --git a/include/seqan/simd/simd_base.h b/include/seqan/simd/simd_base.h
new file mode 100644
index 0000000..22ab483
--- /dev/null
+++ b/include/seqan/simd/simd_base.h
@@ -0,0 +1,319 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Marcel Ehrhardt <marcel.ehrhardt at fu-berlin.de>
+// ==========================================================================
+// generic SIMD interface for SSE3 / AVX2
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_H_
+#define SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_H_
+
+namespace seqan
+{
+
+// a metafunction returning the biggest supported SIMD vector
+template <typename TValue, int LENGTH>
+struct SimdVector;
+
+template <typename TValue, int LENGTH>
+struct Value<SimdVector<TValue, LENGTH> >
+{
+    typedef TValue Type;
+};
+
+template <typename TValue, int LENGTH>
+struct Value<SimdVector<TValue, LENGTH> const> :
+    public Value<SimdVector<TValue, LENGTH> >
+{};
+
+template <typename TValue, int LENGTH_>
+struct LENGTH<SimdVector<TValue, LENGTH_> >
+{
+    enum { VALUE = LENGTH_ };
+};
+
+template <typename TValue, int LENGTH_>
+struct LENGTH<SimdVector<TValue, LENGTH_> const> :
+    public LENGTH<SimdVector<TValue, LENGTH_> >
+{};
+
+// define a concept and its models
+// they allow us to define generic vector functions
+SEQAN_CONCEPT(SimdVectorConcept, (TSimdVector)) {
+    typedef typename Reference<TSimdVector>::Type TReference;
+
+    TSimdVector a;
+
+    SEQAN_CONCEPT_USAGE(SimdVectorConcept)
+    {
+        static_assert(IsSameType<decltype(a[0]), TReference>::VALUE, "Type of a[] should be the same as the reference type of a.");
+    }
+};
+
+template <typename TSimdVector, typename TIsSimdVec>
+struct SimdSwizzleVectorImpl;
+
+/**
+ * SimdSwizzleVector is needed for shuffleVector() as index type.
+ *
+ * ```
+ * using TSimdVector = SimdVector<uint32_t, 4>::Type;
+ * using TSimdSwizzleVector = SimdSwizzleVector<TSimdVector>::Type;
+ *
+ * TSimdVector vec {2, 4, 8, 16}, res;
+ * TSimdSwizzleVector swizzle {3, 2, 0, 2};
+ *
+ * res = shuffleVector(vec, swizzle); // res = {16, 8, 2, 8}
+ * ```
+ */
+template <typename TSimdVector>
+struct SimdSwizzleVector : SimdSwizzleVectorImpl<TSimdVector, typename Is<SimdVectorConcept<TSimdVector> >::Type >
+{};
+
+/**
+ * ```
+ * getValue(a, pos);
+ *
+ * // same as
+ *
+ * a[pos];
+ * ```
+ */
+template <typename TSimdVector, typename TPosition>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename Value<TSimdVector>::Type)
+getValue(TSimdVector const & vector, TPosition const pos);
+
+/**
+ * ```
+ * value(a, pos);
+ *
+ * // same as
+ *
+ * a[pos];
+ * ```
+ */
+template <typename TSimdVector, typename TPosition>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename Value<TSimdVector>::Type)
+value(TSimdVector const & vector, TPosition const pos);
+
+/**
+ * ```
+ * assignValue(a, pos, value);
+ *
+ * // same as
+ *
+ * a[pos] = value;
+ * ```
+ */
+template <typename TSimdVector, typename TPosition, typename TValue2>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+assignValue(TSimdVector & vector, TPosition const pos, TValue2 const value);
+
+template <int ROWS, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+transpose(TSimdVector matrix[ROWS]);
+
+/**
+ * ```
+ * clearVector(a);
+ *
+ * // same as
+ *
+ * for(auto i = 0u; i < LENGTH; ++i)
+ *     c[i] = 0;
+ * ```
+ */
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+clearVector(TSimdVector & vector);
+
+/**
+ * ```
+ * auto c = createVector<SimdVector4Int>(a);
+ *
+ * // same as
+ *
+ * for(auto i = 0u; i < LENGTH; ++i)
+ *     c[i] = a;
+ * ```
+ */
+template <typename TSimdVector, typename TValue>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+createVector(TValue const x);
+
+/**
+ * ```
+ * fillVector(a, 1, 3, 23, 1337);
+ *
+ * // same as
+ *
+ * a[0] = 1;
+ * a[1] = 3;
+ * a[2] = 13;
+ * a[3] = 1337;
+ * ```
+ */
+template <typename TSimdVector, typename ...TValue>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+fillVector(TSimdVector & vector, TValue const... args);
+
+/**
+ * ```
+ * c = cmpEq(a, b);
+ *
+ * // same as
+ *
+ * c = a == b;
+ * ```
+ */
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+cmpEq (TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator==(TSimdVector const & a, TSimdVector const & b);
+
+/**
+ * ```
+ * c = cmpGt(a, b);
+ *
+ * // same as
+ *
+ * c = a > b;
+ * ```
+ */
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+cmpGt (TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator>(TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+max(TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator|(TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector &)
+operator|=(TSimdVector & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator&(TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector &)
+operator&=(TSimdVector & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator~(TSimdVector const & a);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator+(TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator-(TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator*(TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator/(TSimdVector const & a, TSimdVector const & b);
+
+/**
+ * ```
+ * c = andNot(a, b);
+ *
+ * // same as
+ *
+ * for(auto i = 0u; i < LENGTH; ++i)
+ *     c[i] = (~a[i]) & b[i];
+ * ```
+ */
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+andNot(TSimdVector const & a, TSimdVector const & b);
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+shiftRightLogical(TSimdVector const & vector, const int imm);
+
+template <typename TSimdVector, typename TSimdVectorMask>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+blend(TSimdVector const & a, TSimdVector const & b, TSimdVectorMask const & mask);
+
+/**
+ * Unaligned store, i.e. memAddr does not need to be aligned (e.g. SEE4.2 16byte
+ * aligned, AVX2 32byte aligned).
+ */
+template <typename T, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+storeu(T * memAddr, TSimdVector const & vec);
+
+/**
+ * Aligned load, i.e. memAddr MUST be aligned (e.g. SEE4.2 16byte
+ * aligned, AVX2 32byte aligned).
+ */
+template <typename TSimdVector, typename T>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+load(T const * memAddr);
+
+template <typename TValue, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+gather(TValue const * memAddr, TSimdVector const & idx);
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector1> >, TSimdVector1)
+shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices);
+
+// NOTE(rmaerker): Make this function available, also if SIMD is not enabled.
+template <typename TSimdVector, typename TValue>
+inline SEQAN_FUNC_DISABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+createVector(TValue const x)
+{
+    return x;
+}
+
+} // namespace seqan
+
+#endif // SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_H_
diff --git a/include/seqan/simd/simd_base_seqan_impl.h b/include/seqan/simd/simd_base_seqan_impl.h
new file mode 100644
index 0000000..ff224df
--- /dev/null
+++ b/include/seqan/simd/simd_base_seqan_impl.h
@@ -0,0 +1,143 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: David Weese <david.weese at fu-berlin.de>
+//         René Rahn <rene.rahn at fu-berlin.de>
+//         Stefan Budach <stefan.budach at fu-berlin.de>
+// ==========================================================================
+// generic SIMD interface for SSE3 / AVX2
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_H_
+#define SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_H_
+
+#include <utility>
+#include <tuple>
+
+#if defined(PLATFORM_WINDOWS_VS)
+  /* Microsoft C/C++-compatible compiler */
+  #include <intrin.h>
+#elif defined(PLATFORM_GCC) && (defined(__x86_64__) || defined(__i386__))
+  /* GCC-compatible compiler, targeting x86/x86-64 */
+  #include <x86intrin.h>
+#else
+  #warning "No supported platform for SIMD vectorization!"
+#endif
+
+namespace seqan {
+
+#ifdef COMPILER_LINTEL
+#include <type_traits>
+#define SEQAN_VECTOR_CAST_(T, v) static_cast<typename std::decay<T>::type>(v)
+#define SEQAN_VECTOR_CAST_LVALUE_(T, v) static_cast<T>(v)
+#else
+#define SEQAN_VECTOR_CAST_(T, v) reinterpret_cast<T>(v)
+#define SEQAN_VECTOR_CAST_LVALUE_(T, v) reinterpret_cast<T>(v)
+#endif
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Useful Macros
+// ============================================================================
+
+#define SEQAN_DEFINE_SIMD_VECTOR_GETVALUE_(TSimdVector)                                                 \
+template <typename TPosition>                                                                           \
+inline typename Value<TSimdVector>::Type                                                                \
+getValue(TSimdVector & vector, TPosition const pos)                                                     \
+{                                                                                                       \
+    return vector[pos];                                                                                 \
+}
+
+#define SEQAN_DEFINE_SIMD_VECTOR_VALUE_(TSimdVector)                                                    \
+template <typename TPosition>                                                                           \
+inline typename Value<TSimdVector>::Type                                                                \
+value(TSimdVector & vector, TPosition const pos)                                                        \
+{                                                                                                       \
+    return getValue(vector, pos);                                                                       \
+}
+
+#define SEQAN_DEFINE_SIMD_VECTOR_ASSIGNVALUE_(TSimdVector)                                              \
+template <typename TPosition, typename TValue2>                                                         \
+inline void                                                                                             \
+assignValue(TSimdVector & vector, TPosition const pos, TValue2 const value)                             \
+{                                                                                                       \
+    vector[pos] = value;                                                                                \
+}
+
+// Only include following code if simd instructions are enabled.
+#ifdef SEQAN_SIMD_ENABLED
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// a metafunction returning the biggest supported SIMD vector
+template <typename TValue, int LENGTH = SEQAN_SIZEOF_MAX_VECTOR / sizeof(TValue)>
+struct SimdVector;
+
+// internal struct to specialize for vector parameters
+// VEC_SIZE    = Vector size := sizeof(vec)
+// LENGTH      = number of elements := VEC_SIZE / sizeof(InnerValue<TVec>::Type)
+// SCALAR_TYPE = the scalar type of the vector (maybe optional, if the type
+//               doesn't matter for the operation)
+template <int VEC_SIZE, int LENGTH = 0, typename SCALAR_TYPE = void>
+struct SimdParams_
+{};
+
+// internal struct to specialize for matrix parameters
+template <int ROWS, int COLS, int BITS_PER_VALUE>
+struct SimdMatrixParams_
+{};
+
+#define SEQAN_DEFINE_SIMD_VECTOR_(TSimdVector, TValue, SIZEOF_VECTOR)                                           \
+        typedef TValue TSimdVector __attribute__ ((__vector_size__(SIZEOF_VECTOR)));                            \
+        template <> struct SimdVector<TValue, SIZEOF_VECTOR / sizeof(TValue)> {  typedef TSimdVector Type; };   \
+        template <> struct Value<TSimdVector>           { typedef TValue Type; };                               \
+        template <> struct Value<TSimdVector const>:  public Value<TSimdVector> {};                             \
+        template <> struct LENGTH<TSimdVector>          { enum { VALUE = SIZEOF_VECTOR / sizeof(TValue) }; };   \
+        template <> struct LENGTH<TSimdVector const>: public LENGTH<TSimdVector> {};                            \
+        SEQAN_DEFINE_SIMD_VECTOR_GETVALUE_(TSimdVector)                                                         \
+        SEQAN_DEFINE_SIMD_VECTOR_GETVALUE_(TSimdVector const)                                                   \
+        SEQAN_DEFINE_SIMD_VECTOR_VALUE_(TSimdVector)                                                            \
+        SEQAN_DEFINE_SIMD_VECTOR_VALUE_(TSimdVector const)                                                      \
+        SEQAN_DEFINE_SIMD_VECTOR_ASSIGNVALUE_(TSimdVector)                                                      \
+        template <>                                                                                             \
+        SEQAN_CONCEPT_IMPL((TSimdVector),       (SimdVectorConcept));                                           \
+        template <>                                                                                             \
+        SEQAN_CONCEPT_IMPL((TSimdVector const), (SimdVectorConcept));
+#endif  // SEQAN_SIMD_ENABLED
+
+} // namespace seqan
+
+#endif // SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_H_
diff --git a/include/seqan/simd/simd_base_seqan_impl_avx2.h b/include/seqan/simd/simd_base_seqan_impl_avx2.h
new file mode 100644
index 0000000..882c975
--- /dev/null
+++ b/include/seqan/simd/simd_base_seqan_impl_avx2.h
@@ -0,0 +1,1440 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: David Weese <david.weese at fu-berlin.de>
+//         René Rahn <rene.rahn at fu-berlin.de>
+//         Stefan Budach <stefan.budach at fu-berlin.de>
+// ==========================================================================
+// generic SIMD interface for SSE3 / AVX2
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_AVX2_H_
+#define SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_AVX2_H_
+
+namespace seqan {
+
+// SimdParams_<32, 32>: 256bit = 32 elements * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector32Char,     char,           32)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector32SChar,    signed char,    32)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector32UChar,    unsigned char,  32)
+
+// SimdParams_<32, 16>: 256bit = 16 elements * 2 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16Short,    short,          32)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16UShort,   unsigned short, 32)
+
+// SimdParams_<32, 8>: 256bit = 8 elements * 4 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8Int,       int,            32)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8UInt,      unsigned int,   32)
+
+// SimdParams_<32, 4>: 256bit = 4 elements * 8 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4Int64,     int64_t,        32)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4UInt64,    uint64_t,       32)
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// ============================================================================
+// AVX/AVX2 wrappers (256bit vectors)
+// ============================================================================
+
+// --------------------------------------------------------------------------
+// _fillVector (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename ...TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & x,
+            std::index_sequence<0> const &, SimdParams_<32, 32>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi8(std::get<0>(x)));
+}
+
+template <typename TSimdVector, typename ...TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & x,
+            std::index_sequence<0> const &, SimdParams_<32, 16>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi16(std::get<0>(x)));
+}
+
+template <typename TSimdVector, typename ...TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & x,
+            std::index_sequence<0> const &, SimdParams_<32, 8>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi32(std::get<0>(x)));
+}
+
+template <typename TSimdVector, typename ...TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & x,
+            std::index_sequence<0> const &, SimdParams_<32, 4>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi64x(std::get<0>(x)));
+}
+
+template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args, std::index_sequence<INDICES...> const &, SimdParams_<32, 32>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_setr_epi8(std::get<INDICES>(args)...));
+}
+
+template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args, std::index_sequence<INDICES...> const &, SimdParams_<32, 16>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_setr_epi16(std::get<INDICES>(args)...));
+}
+template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args, std::index_sequence<INDICES...> const &, SimdParams_<32, 8>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_setr_epi32(std::get<INDICES>(args)...));
+}
+
+template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args, std::index_sequence<INDICES...> const &, SimdParams_<32, 4>)
+{
+    // reverse argument list 0, 1, 2, 3 -> 3, 2, 1, 0
+#if defined(COMPILER_LINTEL)
+    // NOTE(marehr): Intel linux fails to reverse argument list and only
+    // _mm256_set_epi64x has no reverse equivalent
+    vector = SEQAN_VECTOR_CAST_(TSimdVector,
+                _mm256_set_epi64x(
+                    std::get<3>(args),
+                    std::get<2>(args),
+                    std::get<1>(args),
+                    std::get<0>(args)
+                )
+            );
+#else
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set_epi64x(std::get<sizeof...(INDICES) - 1 - INDICES>(args)...));
+#endif
+}
+
+// --------------------------------------------------------------------------
+// _clearVector (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline void _clearVector(TSimdVector & vector, SimdParams_<32, L>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_setzero_si256());
+}
+
+// --------------------------------------------------------------------------
+// _createVector (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TValue>
+inline TSimdVector _createVector(TValue const x, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi8(x));
+}
+
+template <typename TSimdVector, typename TValue>
+inline TSimdVector _createVector(TValue const x, SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi16(x));
+}
+
+template <typename TSimdVector, typename TValue>
+inline TSimdVector _createVector(TValue const x, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi32(x));
+}
+
+template <typename TSimdVector, typename TValue>
+inline TSimdVector _createVector(TValue const x, SimdParams_< 32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_set1_epi64x(x));
+}
+
+// --------------------------------------------------------------------------
+// _cmpEq (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpeq_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                             SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpeq_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpeq_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpeq_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _cmpGt (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<32, 32, int8_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpgt_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                             SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<32, 32, uint8_t>)
+{
+    // There is no unsigned cmpgt, we reduce it to the signed case.
+    // Note that 0x80 = ~0x7F (prevent overflow messages).
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_cmpgt_epi8(
+                                  _mm256_xor_si256(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_set1_epi8(~0x7F)),
+                                  _mm256_xor_si256(SEQAN_VECTOR_CAST_(const __m256i&, b), _mm256_set1_epi8(~0x7F))));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<32, 16, int16_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpgt_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<32, 16, uint16_t>)
+{
+    // There is no unsigned cmpgt, we reduce it to the signed case.
+    // Note that 0x8000 = ~0x7FFF (prevent overflow messages).
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_cmpgt_epi16(
+                                  _mm256_xor_si256(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_set1_epi16(~0x7FFF)),
+                                  _mm256_xor_si256(SEQAN_VECTOR_CAST_(const __m256i&, b), _mm256_set1_epi16(~0x7FFF))));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8, int32_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpgt_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8, uint32_t>)
+{
+    // There is no unsigned cmpgt, we reduce it to the signed case.
+    // Note that 0x80000000 = ~0x7FFFFFFF (prevent overflow messages).
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_cmpgt_epi32(
+                                  _mm256_xor_si256(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_set1_epi32(~0x7FFFFFFF)),
+                                  _mm256_xor_si256(SEQAN_VECTOR_CAST_(const __m256i&, b), _mm256_set1_epi32(~0x7FFFFFFF))));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<32, 4, int64_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_cmpgt_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<32, 4, uint64_t>)
+{
+    // There is no unsigned cmpgt, we reduce it to the signed case.
+    // Note that 0x8000000000000000ul = ~0x7FFFFFFFFFFFFFFFul (prevent overflow messages).
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_cmpgt_epi64(
+                                  _mm256_xor_si256(SEQAN_VECTOR_CAST_(const __m256i&, a) ,_mm256_set1_epi64x(~0x7FFFFFFFFFFFFFFFul)),
+                                  _mm256_xor_si256(SEQAN_VECTOR_CAST_(const __m256i&, b), _mm256_set1_epi64x(~0x7FFFFFFFFFFFFFFFul))));
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseOr (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _bitwiseOr(TSimdVector & a, TSimdVector & b, SimdParams_<32, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_or_si256(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                           SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseAnd (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _bitwiseAnd(TSimdVector & a, TSimdVector & b, SimdParams_<32, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_and_si256(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                            SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseAnd(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_and_ps(SEQAN_VECTOR_CAST_(const __m256&, a),
+                                                         SEQAN_VECTOR_CAST_(const __m256&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseAnd(TSimdVector & a, TSimdVector & b, SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_and_pd(SEQAN_VECTOR_CAST_(const __m256d&, a),
+                                                         SEQAN_VECTOR_CAST_(const __m256d&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseAndNot (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _bitwiseAndNot(TSimdVector & a, TSimdVector & b, SimdParams_<32, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_andnot_si256(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseNot (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseNot(TSimdVector & a, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_cmpeq_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_setzero_si256()));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseNot(TSimdVector & a, SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_cmpeq_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_setzero_si256()));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseNot(TSimdVector & a, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_cmpeq_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_setzero_si256()));
+
+}
+template <typename TSimdVector>
+inline TSimdVector _bitwiseNot(TSimdVector & a, SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_cmpeq_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a), _mm256_setzero_si256()));
+}
+
+// --------------------------------------------------------------------------
+// _divide (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _divide(TSimdVector & a, int b, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_div_epi8(a, _mm256_set1_epi8(b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _divide(TSimdVector & a, int b, SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_div_epi16(a, _mm256_set1_epi16(b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _divide(TSimdVector & a, int b, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_div_epi32(a, _mm256_set1_epi32(b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _divide(TSimdVector & a, int b, SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_div_epi64(a, _mm256_set1_epi64x(b)));
+}
+
+// --------------------------------------------------------------------------
+// _add (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _add(TSimdVector & a, TSimdVector & b, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_add_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _add(TSimdVector & a, TSimdVector & b, SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_add_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _add(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_add_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _add(TSimdVector & a, TSimdVector & b, SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_add_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _sub (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _sub(TSimdVector & a, TSimdVector & b, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_sub_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _sub(TSimdVector & a, TSimdVector & b, SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_sub_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _sub(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_sub_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _sub(TSimdVector & a, TSimdVector & b, SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_sub_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _mult (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _mult(TSimdVector & a, TSimdVector &/*b*/, SimdParams_<32, 32>)
+{
+    SEQAN_SKIP_TEST;
+    SEQAN_ASSERT_FAIL("AVX2 intrinsics for multiplying 8 bit values not implemented!");
+    return a;
+}
+
+template <typename TSimdVector>
+inline TSimdVector _mult(TSimdVector & a, TSimdVector & b, SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_mullo_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                 SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _mult(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_mullo_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                 SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _mult(TSimdVector & a, TSimdVector &/*b*/, SimdParams_<32, 4>)
+{
+    SEQAN_SKIP_TEST;
+    SEQAN_ASSERT_FAIL("AVX2 intrinsics for multiplying 64 bit values not implemented!");
+    return a;
+}
+
+// --------------------------------------------------------------------------
+// _max (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<32, 32, int8_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_max_epi8(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<32, 32, uint8_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_max_epu8(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<32, 16, int16_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_max_epi16(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<32, 16, uint16_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_max_epu16(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8, int32_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_max_epi32(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<32, 8, uint32_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_max_epu32(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m256i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<32, 4, int64_t>)
+{
+    #if defined(__AVX512VL__)
+        return SEQAN_VECTOR_CAST_(TSimdVector,
+                                  _mm256_max_epi64(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                   SEQAN_VECTOR_CAST_(const __m256i&, b)));
+    #else // defined(__AVX512VL__)
+        return blend(b, a, cmpGt(a, b));
+    #endif // defined(__AVX512VL__)
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<32, 4, uint64_t>)
+{
+    #if defined(__AVX512VL__)
+        return SEQAN_VECTOR_CAST_(TSimdVector,
+                                  _mm256_max_epu64(SEQAN_VECTOR_CAST_(const __m256i&, a),
+                                                   SEQAN_VECTOR_CAST_(const __m256i&, b)));
+    #else // defined(__AVX512VL__)
+        return blend(b, a, cmpGt(a, b));
+    #endif // defined(__AVX512VL__)
+}
+
+// --------------------------------------------------------------------------
+// _blend (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TSimdVectorMask, int L>
+inline TSimdVector _blend(TSimdVector const & a, TSimdVector const & b, TSimdVectorMask const & mask, SimdParams_<32, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm256_blendv_epi8(SEQAN_VECTOR_CAST_(const __m256i &, a),
+                                                 SEQAN_VECTOR_CAST_(const __m256i &, b),
+                                                 SEQAN_VECTOR_CAST_(const __m256i &, mask)));
+}
+
+// --------------------------------------------------------------------------
+// _storeu (256bit)
+// --------------------------------------------------------------------------
+
+template <typename T, typename TSimdVector, int L>
+inline void _storeu(T * memAddr, TSimdVector & vec, SimdParams_<32, L>)
+{
+    _mm256_storeu_si256((__m256i*)memAddr, SEQAN_VECTOR_CAST_(const __m256i&, vec));
+}
+
+// ----------------------------------------------------------------------------
+// Function _load() 256bit
+// ----------------------------------------------------------------------------
+
+template <typename TSimdVector, typename T, int L>
+inline TSimdVector _load(T const * memAddr, SimdParams_<32, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_load_si256((__m256i const *) memAddr));
+}
+
+// --------------------------------------------------------------------------
+// _shiftRightLogical (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_srli_epi16(SEQAN_VECTOR_CAST_(const __m256i &, vector), imm) & _mm256_set1_epi8(0xff >> imm));
+}
+template <typename TSimdVector>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_srli_epi16(SEQAN_VECTOR_CAST_(const __m256i &, vector), imm));
+}
+template <typename TSimdVector>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_srli_epi32(SEQAN_VECTOR_CAST_(const __m256i &, vector), imm));
+}
+template <typename TSimdVector>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm256_srli_epi64(SEQAN_VECTOR_CAST_(const __m256i &, vector), imm));
+}
+
+// --------------------------------------------------------------------------
+// Extend sign from integer types 256bit
+// --------------------------------------------------------------------------
+
+inline __m256i
+seqan_mm256_i16sign_extend_epis8(__m256i const & v)
+{
+    return _mm256_or_si256( // extend sign (v | hi-bits)
+        v,
+        _mm256_and_si256( // select hi-bits (hi-bits = msk & 0xff00)
+            _mm256_sub_epi16( // msk = msb - 1
+                _mm256_andnot_si256( //msb = ~v & 0x80 (select msb)
+                    v,
+                    _mm256_set1_epi16(0x80)
+                ),
+                _mm256_set1_epi16(1)
+            ),
+            _mm256_set1_epi16(static_cast<uint16_t>(0xff00u))
+        )
+    );
+}
+
+inline __m256i
+seqan_mm256_i32sign_extend_epis8(__m256i const & v)
+{
+    return _mm256_or_si256( // extend sign (v | hi-bits)
+        v,
+        _mm256_and_si256( // select hi-bits (hi-bits = msk & 0xffffff00u)
+            _mm256_sub_epi32( // msk = msb - 1
+                _mm256_andnot_si256( //msb = ~v & 0x80 (select msb)
+                    v,
+                    _mm256_set1_epi32(0x80)
+                ),
+                _mm256_set1_epi32(1)
+            ),
+            _mm256_set1_epi32(static_cast<uint32_t>(0xffffff00u))
+        )
+    );
+}
+
+inline __m256i
+seqan_mm256_i32sign_extend_epis16(__m256i const & v)
+{
+    return _mm256_or_si256( // extend sign (v | hi-bits)
+        v,
+        _mm256_and_si256( // select hi-bits (hi-bits = msk & 0xffff0000u)
+            _mm256_sub_epi32( // msk = msb - 1
+                _mm256_andnot_si256( //msb = ~v & 0x8000 (select msb)
+                    v,
+                    _mm256_set1_epi32(0x8000)
+                ),
+                _mm256_set1_epi32(1)
+            ),
+            _mm256_set1_epi32(static_cast<uint32_t>(0xffff0000u))
+        )
+    );
+}
+
+inline __m256i
+seqan_mm256_i64sign_extend_epis8(__m256i const & v)
+{
+    return _mm256_or_si256( // extend sign (v | hi-bits)
+        v,
+        _mm256_and_si256( // select hi-bits (hi-bits = msk & 0xffffffffffffff00ul)
+            _mm256_sub_epi64( // msk = msb - 1
+                _mm256_andnot_si256( //msb = ~v & 0x80 (select msb)
+                    v,
+                    _mm256_set1_epi64x(0x80)
+                ),
+                _mm256_set1_epi64x(1)
+            ),
+            _mm256_set1_epi64x(static_cast<uint64_t>(0xffffffffffffff00ul))
+        )
+    );
+}
+
+inline __m256i
+seqan_mm256_i64sign_extend_epis16(__m256i const & v)
+{
+    return _mm256_or_si256( // extend sign (v | hi-bits)
+        v,
+        _mm256_and_si256( // select hi-bits (hi-bits = msk & 0xffffffffffff0000ul)
+            _mm256_sub_epi64( // msk = msb - 1
+                _mm256_andnot_si256( //msb = ~v & 0x8000 (select msb)
+                    v,
+                    _mm256_set1_epi64x(0x8000)
+                ),
+                _mm256_set1_epi64x(1)
+            ),
+            _mm256_set1_epi64x(static_cast<uint64_t>(0xffffffffffff0000ul))
+        )
+    );
+}
+
+inline __m256i
+seqan_mm256_i64sign_extend_epis32(__m256i const & v)
+{
+    return _mm256_or_si256( // extend sign (v | hi-bits)
+        v,
+        _mm256_and_si256( // select hi-bits (hi-bits = msk & 0xffffffffffff0000ul)
+            _mm256_sub_epi64( // msk = msb - 1
+                _mm256_andnot_si256( //msb = ~v & 0x80000000 (select msb)
+                    v,
+                    _mm256_set1_epi64x(0x80000000)
+                ),
+                _mm256_set1_epi64x(1)
+            ),
+            _mm256_set1_epi64x(static_cast<uint64_t>(0xffffffff00000000ul))
+        )
+    );
+}
+
+// --------------------------------------------------------------------------
+// _gather (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TValue, typename TSize, TSize SCALE>
+inline __m256i
+seqan_mm256_i8gather_epi(TValue const * memAddr,
+                         __m256i const & idx,
+                         std::integral_constant<TSize, SCALE> const & /*scale*/)
+{
+    // mem:    ( 0,  3,  6,  9 | 12, 15, 18, 21 | 24, 27, 30, 33 | 36, 39, 42, 45 || 48, 51, 54, 57 | 60, 63, 66, 69 | 72, 75, 78, 81 | 84, 87, 90, 93)
+    // idx:    (31, 30, 29, 28 | 27, 26, 25, 24 | 23, 22, 21, 20 | 19, 18, 17, 16 || 15, 14, 13, 12 | 11, 10,  9,  8 |  7,  6,  5,  4 |  3,  2,  1,  0)
+    // pack:   (93, 90, 87, 84 | 81, 78, 75, 72 | 69, 66, 63, 60 | 57, 54, 51, 48 || 45, 42, 39, 36 | 33, 30, 27, 24 | 21, 18, 15, 12 |  9,  6,  3,  0)
+    return _mm256_packus_epi16(
+        // pckLow: (93,  0, 90,  0 | 87,  0, 84,  0 | 81,  0, 78,  0 | 75,  0, 72,  0 || 45,  0, 42,  0 | 39,  0, 36,  0 | 33,  0, 30,  0 | 27,  0, 24,  0)
+        _mm256_packus_epi16(
+            // mskLL:  (93,  0,  0,  0 | 90,  0,  0,  0 | 87,  0,  0,  0 | 84,  0,  0,  0 || 45,  0,  0,  0 | 42,  0,  0,  0 | 39,  0,  0,  0 | 36,  0,  0,  0)
+            _mm256_and_si256(
+                // gtrLL:  (93, 31, 30, 29 | 90, 93, 31, 30 | 87, 90, 93, 31 | 84, 87, 90, 93 || 45, 48, 51, 54 | 42, 45, 48, 51 | 39, 42, 45, 48 | 36, 39, 42, 45)
+                _mm256_i32gather_epi32(
+                    (const int *) memAddr,
+                    // lowlow: (31,  0,  0,  0 | 30,  0,  0,  0 | 29,  0,  0,  0 | 28,  0,  0,  0 || 15,  0,  0,  0 | 14,  0,  0,  0 | 13,  0,  0,  0 | 12,  0,  0,  0)
+                    _mm256_shuffle_epi8(idx, __m256i {
+                        ~0xFF000000FFl | 0x0100000000, ~0xFF000000FFl | 0x0300000002,
+                        ~0xFF000000FFl | 0x0100000000, ~0xFF000000FFl | 0x0300000002
+                    }),
+                    SCALE
+                ),
+                _mm256_set1_epi32(0xFF)
+            ),
+            // mskLH:  (81,  0,  0,  0 | 78,  0,  0,  0 | 75,  0,  0,  0 | 72,  0,  0,  0 || 33,  0,  0,  0 | 30,  0,  0,  0 | 27,  0,  0,  0 | 24,  0,  0,  0)
+            _mm256_and_si256(
+                // gtrLH:  (81, 84, 87, 90 | 78, 81, 84, 87 | 75, 78, 81, 84 | 72, 75, 78, 81 || 33, 36, 39, 42 | 30, 33, 36, 39 | 27, 30, 33, 36 | 24, 27, 30, 33)
+                _mm256_i32gather_epi32(
+                    (const int *) memAddr,
+                    // lowhig: (27,  0,  0,  0 | 26,  0,  0,  0 | 25,  0,  0,  0 | 24,  0,  0,  0 || 11,  0,  0,  0 | 10,  0,  0,  0 |  9,  0,  0,  0 |  8,  0,  0,  0)
+                    _mm256_shuffle_epi8(idx, __m256i {
+                        ~0xFF000000FFl | 0x0500000004, ~0xFF000000FFl | 0x0700000006,
+                        ~0xFF000000FFl | 0x0500000004, ~0xFF000000FFl | 0x0700000006
+                    }),
+                    SCALE
+                ),
+                _mm256_set1_epi32(0xFF)
+            )
+        ),
+        // pckHih: (69,  0, 66,  0 | 63,  0, 60,  0 | 57,  0, 54,  0 | 51,  0, 48,  0 || 21,  0, 18,  0 | 15,  0, 12,  0 |  9,  0,  6,  0 |  3,  0,  0,  0)
+        _mm256_packus_epi16(
+            // mskHL:  (69,  0,  0,  0 | 66,  0,  0,  0 | 63,  0,  0,  0 | 60,  0,  0,  0 || 21,  0,  0,  0 | 18,  0,  0,  0 | 15,  0,  0,  0 | 12,  0,  0,  0)
+            _mm256_and_si256(
+                // gtrHL:  (69, 72, 75, 78 | 66, 69, 72, 75 | 63, 66, 69, 72 | 60, 63, 66, 69 || 21, 24, 27, 30 | 18, 21, 24, 27 | 15, 18, 21, 24 | 12, 15, 18, 21)
+                _mm256_i32gather_epi32(
+                    (const int *) memAddr,
+                    // higlow: (23,  0,  0,  0 | 22,  0,  0,  0 | 21,  0,  0,  0 | 20,  0,  0,  0 ||  7,  0,  0,  0 |  6,  0,  0,  0 |  5,  0,  0,  0 |  4,  0,  0,  0)
+                    _mm256_shuffle_epi8(idx, __m256i {
+                        ~0xFF000000FFl | 0x0900000008, ~0xFF000000FFl | 0x0B0000000A,
+                        ~0xFF000000FFl | 0x0900000008, ~0xFF000000FFl | 0x0B0000000A
+                    }),
+                    SCALE
+                ),
+                _mm256_set1_epi32(0xFF)
+            ),
+            // mskHH:  (57,  0,  0,  0 | 54,  0,  0,  0 | 51,  0,  0,  0 | 48,  0,  0,  0 ||  9,  0,  0,  0 |  6,  0,  0,  0 |  3,  0,  0,  0 |  0,  0,  0,  0)
+            _mm256_and_si256(
+                // gtrHH:  (57, 60, 63, 66 | 54, 57, 60, 63 | 51, 54, 57, 60 | 48, 51, 54, 57 ||  9, 12, 15, 18 |  6,  9, 12, 15 |  3,  6,  9, 12 |  0,  3,  6,  9)
+                _mm256_i32gather_epi32(
+                    (const int *) memAddr,
+                    // highig: (19,  0,  0,  0 | 18,  0,  0,  0 | 17,  0,  0,  0 | 16,  0,  0,  0 ||  3,  0,  0,  0 |  2,  0,  0,  0 |  1,  0,  0,  0 |  0,  0,  0,  0)
+                    _mm256_shuffle_epi8(idx, __m256i {
+                        ~0xFF000000FFl | 0x0D0000000C, ~0xFF000000FFl | 0x0F0000000E,
+                        ~0xFF000000FFl | 0x0D0000000C, ~0xFF000000FFl | 0x0F0000000E
+                    }),
+                    SCALE
+                ),
+                _mm256_set1_epi32(0xFF)
+            )
+        )
+    );
+}
+
+template <typename TValue, typename TSize, TSize SCALE>
+inline __m256i
+seqan_mm256_i16gather_epi(TValue const * memAddr,
+                          __m256i const & idx,
+                          std::integral_constant<TSize, SCALE> const & /*scale*/)
+{
+    using TUnsignedValue = typename MakeUnsigned<TValue>::Type;
+
+    // The cast makes sure that the max value of TValue = (u)int64_t and
+    // (u)int32_t will be max value of int16_t (i.e. `~0` in int16_t), because
+    // the resulting __m256i can only hold int16_t values.
+    //
+    // NOTE(marehr): the masking is only needed for TValue = (u)int8_t and
+    // (u)int16_t. It could be omitted if _mm256_packus_epi32 would be exchanged
+    // by _mm256_packs_epi32, because for (u)int32_t and (u)int64_t the masking
+    // operations are basically the identity function.
+    constexpr int const mask = static_cast<uint16_t>(MaxValue<TUnsignedValue>::VALUE);
+
+    // 1. Unpack low idx values and interleave with 0 and gather from memAddr.
+    // 2. Unpack high idx values and interleave with 0, than gather from memAddr.
+    // 3. Merge 2 8x32 vectors into 1x16 vector by signed saturation. This operation reverts the interleave by the unpack operations above.
+    //
+    // The following is an example for SimdVector<uint16_t, 16> idx and uint16_t
+    // const * memAddr:
+    // mem:    ( 0,  0,  3,  0 |  6,  0,  9,  0 | 12,  0, 15,  0 | 18,  0, 21,  0 || 24,  0, 27,  0 | 30,  0, 33,  0 | 36,  0, 39,  0 | 42,  0, 45,  0)
+    // idx:    (15,  0, 14,  0 | 13,  0, 12,  0 | 11,  0, 10,  0 |  9,  0,  8,  0 ||  7,  0,  6,  0 |  5,  0,  4,  0 |  3,  0,  2,  0 |  1,  0,  0,  0)
+    // pack:   (45,  0, 42,  0 | 39,  0, 36,  0 | 33,  0, 30,  0 | 27,  0, 24,  0 || 21,  0, 18,  0 | 15,  0, 12,  0 |  9,  0,  6,  0 |  3,  0,  0,  0)
+    return _mm256_packus_epi32(
+        // mskLow: (45,  0,  0,  0 | 42,  0,  0,  0 | 39,  0,  0,  0 | 36,  0,  0,  0 || 21,  0,  0,  0 | 18,  0,  0,  0 | 15,  0,  0,  0 | 12,  0,  0,  0)
+        _mm256_and_si256(
+            // gtrLow: (45,  0, 15,  0 | 42,  0, 45,  0 | 39,  0, 42,  0 | 36,  0, 39,  0 || 21,  0, 24,  0 | 18,  0, 21,  0 | 15,  0, 18,  0 | 12,  0, 15,  0)
+            _mm256_i32gather_epi32(
+                (const int *) memAddr,
+                // low:    (15,  0,  0,  0 | 14,  0,  0,  0 | 13,  0,  0,  0 | 12,  0,  0,  0 ||  7,  0,  0,  0 |  6,  0,  0,  0 |  5,  0,  0,  0 |  4,  0,  0,  0)
+                _mm256_unpacklo_epi16(
+                    idx, _mm256_set1_epi16(0)
+                ),
+                SCALE
+            ),
+            _mm256_set1_epi32(mask)
+        ),
+        // mskHih: (33,  0,  0,  0 | 30,  0,  0,  0 | 27,  0,  0,  0 | 24,  0,  0,  0 ||  9,  0,  0,  0 |  6,  0,  0,  0 |  3,  0,  0,  0 |  0,  0,  0,  0)
+        _mm256_and_si256(
+            // gtrHih: (33,  0, 36,  0 | 30,  0, 33,  0 | 27,  0, 30,  0 | 24,  0, 27,  0 ||  9,  0, 12,  0 |  6,  0,  9,  0 |  3,  0,  6,  0 |  0,  0,  3,  0)
+            _mm256_i32gather_epi32(
+                (const int *) memAddr,
+                // high:   (11,  0,  0,  0 | 10,  0,  0,  0 |  9,  0,  0,  0 |  8,  0,  0,  0 ||  3,  0,  0,  0 |  2,  0,  0,  0 |  1,  0,  0,  0 |  0,  0,  0,  0)
+                _mm256_unpackhi_epi16(
+                    idx, _mm256_set1_epi16(0)
+                ),
+                SCALE
+            ),
+            _mm256_set1_epi32(mask)
+        )
+    );
+}
+
+template <typename TValue, typename TSize, TSize SCALE>
+inline __m256i
+seqan_mm256_i32gather_epi(TValue const * memAddr,
+                          __m256i const & idx,
+                          std::integral_constant<TSize, SCALE> const & /*scale*/)
+{
+    using TUnsignedValue = typename MakeUnsigned<TValue>::Type;
+    constexpr auto const mask = static_cast<uint32_t>(MaxValue<TUnsignedValue>::VALUE);
+
+    return _mm256_and_si256(
+        _mm256_i32gather_epi32((const int *) memAddr, idx, SCALE),
+        _mm256_set1_epi32(mask)
+    );
+}
+
+template <typename TValue, typename TSize, TSize SCALE>
+inline __m256i
+seqan_mm256_i64gather_epi(TValue const * memAddr,
+                          __m256i const & idx,
+                          std::integral_constant<TSize, SCALE> const & /*scale*/)
+{
+    using TUnsignedValue = typename MakeUnsigned<TValue>::Type;
+    constexpr auto const mask = static_cast<uint64_t>(MaxValue<TUnsignedValue>::VALUE);
+
+    return _mm256_and_si256(
+        _mm256_i64gather_epi64((const long long *) memAddr, idx, SCALE),
+        _mm256_set1_epi64x(mask)
+    );
+}
+
+template <typename TValue, typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(TValue const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+        seqan_mm256_i8gather_epi(
+            memAddr,
+            SEQAN_VECTOR_CAST_(__m256i const &, idx),
+            scale
+        )
+    );
+}
+
+template <typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(int8_t const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 16>)
+{
+    // Note that memAddr is a signed integer type, thus a cast would extend the
+    // sign. E.g., -3 = 253 in 8 bit, but would be 65533 in 16 bit.
+    // Use _gather(uint8_t) and extend the sign to [u]int16_t.
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i16sign_extend_epis8(
+            seqan_mm256_i16gather_epi(
+                memAddr,
+                SEQAN_VECTOR_CAST_(__m256i const &, idx),
+                scale
+            )
+        )
+    );
+}
+
+template <typename TValue, typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(TValue const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 16>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i16gather_epi(
+            memAddr,
+            SEQAN_VECTOR_CAST_(__m256i const &, idx),
+            scale
+        )
+    );
+}
+
+template <typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(int8_t const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 8>)
+{
+    // Note that memAddr is a signed integer type, thus a cast would extend the
+    // sign.
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i32sign_extend_epis8(
+            seqan_mm256_i32gather_epi(
+                memAddr,
+                SEQAN_VECTOR_CAST_(__m256i const &, idx),
+                scale
+            )
+        )
+    );
+}
+
+template <typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(int16_t const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 8>)
+{
+    // Note that memAddr is a signed integer type, thus a cast would extend the
+    // sign.
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i32sign_extend_epis16(
+            seqan_mm256_i32gather_epi(
+                memAddr,
+                SEQAN_VECTOR_CAST_(__m256i const &, idx),
+                scale
+            )
+        )
+    );
+}
+
+template <typename TValue, typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(TValue const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 8>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i32gather_epi(
+            memAddr,
+            SEQAN_VECTOR_CAST_(__m256i const &, idx),
+            scale
+        )
+    );
+}
+
+template <typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(int8_t const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i64sign_extend_epis8(
+            seqan_mm256_i64gather_epi(
+                memAddr,
+                SEQAN_VECTOR_CAST_(__m256i const &, idx),
+                scale
+            )
+        )
+    );
+}
+
+template <typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(int16_t const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i64sign_extend_epis16(
+            seqan_mm256_i64gather_epi(
+                memAddr,
+                SEQAN_VECTOR_CAST_(__m256i const &, idx),
+                scale
+            )
+        )
+    );
+}
+
+template <typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(int32_t const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i64sign_extend_epis32(
+            seqan_mm256_i64gather_epi(
+                memAddr,
+                SEQAN_VECTOR_CAST_(__m256i const &, idx),
+                scale
+            )
+        )
+    );
+}
+
+template <typename TValue, typename TSimdVector, typename TSize, TSize SCALE>
+inline TSimdVector
+_gather(TValue const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & scale,
+        SimdParams_<32, 4>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector,
+        seqan_mm256_i64gather_epi(
+            memAddr,
+            SEQAN_VECTOR_CAST_(__m256i const &, idx),
+            scale
+        )
+    );
+}
+
+// --------------------------------------------------------------------------
+// _shuffleVector (256bit)
+// --------------------------------------------------------------------------
+
+inline __m256i
+seqan_m256_shuffle_epi8(__m256i const & vector, __m256i const & indices)
+{
+    return _mm256_xor_si256(
+        // shuffle bytes from the lower bytes of vector
+        _mm256_shuffle_epi8(
+            // repeat twice the low bytes of vector in a new __m256i vector i.e.
+            //   vh[127:0] = v[127:0]
+            //   vh[255:128] = v[127:0]
+            _mm256_broadcastsi128_si256(
+                 _mm256_extracti128_si256(vector, 0)
+            ),
+            // ((indices[i] << 3) & 0b1000 0000) ^ indices[i]:
+            //   Adds the 5th bit of indices[i] as most significant bit. If the
+            //   5th bit is set, that means that indices[i] >= 16.
+            //   r = _mm256_shuffle_epi8(vl, indices) will set r[i] = 0 if the
+            //   most significant bit of indices[i] is 1. Since this bit is the
+            //   5th bit, r[i] = 0 if indices[i] >= 16 and r[i] = vl[indices[i]]
+            //   if indices[i] < 16.
+            _mm256_xor_si256(
+                _mm256_and_si256(
+                    _mm256_slli_epi16(indices, 3),
+                    _mm256_set1_epi8(-127) // 0b1000 0000
+                ),
+                indices
+            )
+        ),
+        // shuffle bytes from the higher bytes of vector
+        _mm256_shuffle_epi8(
+            // repeat twice the higher bytes of vector in a new __m256i vector
+            // i.e.
+            //   vh[127:0] = v[255:128]
+            //   vh[255:128] = v[255:128]
+            _mm256_broadcastsi128_si256(
+                 _mm256_extracti128_si256(vector, 1)
+            ),
+            // indices[i] - 16:
+            //   r = _mm256_shuffle_epi8(vh, indices)
+            //   will return r[i] = 0 if the most significant bit of the byte
+            //   indices[i] is 1. Thus, indices[i] - 16 will select all high
+            //   bytes in vh, i.e. r[i] = vh[indices[i] - 16], if indices[i] >=
+            //   16 and r[i] = 0 if indices[i] < 16.
+            _mm256_sub_epi8(
+                indices,
+                _mm256_set1_epi8(16)
+            )
+        )
+    );
+}
+
+inline __m256i
+seqan_m256_shuffle_epi16(const __m256i a, const __m256i b)
+{
+    // multiply by 2
+    __m256i idx = _mm256_slli_epi16(
+        _mm256_permute4x64_epi64(b, 0b01010000),
+        1
+    );
+    // _print(_mm256_add_epi8(idx, _mm256_set1_epi8(1)));
+    // _print(        _mm256_unpacklo_epi8(
+    //             idx,
+    //             _mm256_add_epi8(idx, _mm256_set1_epi8(1))
+    //         ));
+    return seqan_m256_shuffle_epi8(
+        a,
+        // interleave idx[15:0]   = 2*indices[15],   ..., 2*indices[0]
+        // with       idx[15:0]+1 = 2*indices[15]+1, ..., 2*indices[0]+1
+        // => 2*indices[15]+1, 2*indices[15], ..., 2*indices[0]+1, 2*indices[0]
+        _mm256_unpacklo_epi8(
+            idx,
+            _mm256_add_epi8(idx, _mm256_set1_epi8(1))
+        )
+    );
+}
+
+inline __m256i
+seqan_m256_shuffle_epi32(const __m256i a, const __m256i b)
+{
+    // multiply by 4
+    __m256i idx = _mm256_slli_epi16(
+        _mm256_permutevar8x32_epi32(b, __m256i {0x0, 0x0, 0x1, 0x0}),
+        2
+    );
+    return seqan_m256_shuffle_epi8(
+        a,
+        // interleave 4*indices[7]+1, 4*indices[7]+0; ..., 4*indices[0]+1, 4*indices[0]+0
+        // with       4*indices[7]+3, 4*indices[7]+2; ..., 4*indices[0]+3, 4*indices[0]+2
+        // => 4*indices[7]+3, 4*indices[7]+2; 4*indices[7]+1, 4*indices[7]+0;
+        //    ...
+        //    4*indices[0]+3, 4*indices[0]+2; 4*indices[0]+1, 4*indices[0]+0
+        _mm256_unpacklo_epi16(
+            // interleave idx[7:0]+0 = 4*indices[7]+0; ...; 4*indices[0]+0
+            // with       idx[7:0]+1 = 4*indices[7]+1; ...; 4*indices[0]+1
+            // => 4*indices[7]+1; 4*indices[7]+0; ...; 4*indices[0]+1; 4*indices[0]+0
+            _mm256_unpacklo_epi8(
+                idx,
+                _mm256_add_epi8(idx, _mm256_set1_epi8(1))
+            ),
+            // interleave idx[7:0]+2 = 4*indices[7]+2; ...; 4*indices[0]+2
+            // with       idx[7:0]+3 = 4*indices[7]+3; ...; 4*indices[0]+3
+            // => 4*indices[7]+3; 4*indices[7]+2; ...; 4*indices[0]+3; 4*indices[0]+2
+            _mm256_unpacklo_epi8(
+                _mm256_add_epi8(idx, _mm256_set1_epi8(2)),
+                _mm256_add_epi8(idx, _mm256_set1_epi8(3))
+            )
+    ));
+}
+
+#define seqan_mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)
+
+inline __m256i
+seqan_m256_shuffle_epi64(const __m256i a, const __m256i b)
+{
+    __m128i lowidx = _mm256_extracti128_si256(
+        // multiply by 8
+        _mm256_slli_epi16(b, 3),
+        0
+    );
+
+    __m256i idx = seqan_mm256_set_m128i(
+        _mm_srli_si128(lowidx, 2),
+        lowidx
+    );
+
+    return seqan_m256_shuffle_epi8(
+        a,
+        _mm256_unpacklo_epi32(
+            // interleave 8*indices[3]+1, 8*indices[3]+0; ..., 8*indices[0]+1, 8*indices[0]+0
+            // with       8*indices[3]+3, 8*indices[3]+2; ..., 8*indices[0]+3, 8*indices[0]+2
+            // => 8*indices[3]+3, 8*indices[3]+2; 8*indices[3]+1, 8*indices[3]+0;
+            //    ...
+            //    8*indices[0]+3, 8*indices[0]+2; 8*indices[0]+1, 8*indices[0]+0
+            _mm256_unpacklo_epi16(
+                // interleave idx[3:0]+0 = 8*indices[3]+0; ...; 8*indices[0]+0
+                // with       idx[3:0]+1 = 8*indices[3]+1; ...; 8*indices[0]+1
+                // => 8*indices[3]+1; 8*indices[3]+0; ...; 8*indices[0]+1; 8*indices[0]+0
+               _mm256_unpacklo_epi8(
+                   idx,
+                   _mm256_add_epi8(idx, _mm256_set1_epi8(1))
+               ),
+               // interleave idx[3:0]+2 = 8*indices[3]+2; ...; 8*indices[0]+2
+               // with       idx[3:0]+3 = 8*indices[3]+3; ...; 8*indices[0]+3
+               // => 8*indices[3]+3; 8*indices[3]+2; ...; 8*indices[0]+3; 8*indices[0]+2
+               _mm256_unpacklo_epi8(
+                   _mm256_add_epi8(idx, _mm256_set1_epi8(2)),
+                   _mm256_add_epi8(idx, _mm256_set1_epi8(3))
+               )
+           ),
+           // interleave 8*indices[3]+5, 8*indices[3]+4; ..., 8*indices[0]+5, 8*indices[0]+4
+           // with       8*indices[3]+7, 8*indices[3]+6; ..., 8*indices[0]+7, 8*indices[0]+6
+           // => 8*indices[3]+7, 8*indices[3]+6; 8*indices[3]+5, 8*indices[3]+4;
+           //    ...
+           //    8*indices[0]+7, 8*indices[0]+6; 8*indices[0]+5, 8*indices[0]+4
+            _mm256_unpacklo_epi16(
+                // interleave idx[3:0]+4 = 8*indices[3]+4; ...; 8*indices[0]+4
+                // with       idx[3:0]+5 = 8*indices[3]+5; ...; 8*indices[0]+5
+                // => 8*indices[3]+5; 8*indices[3]+4; ...; 8*indices[0]+5; 8*indices[0]+4
+                _mm256_unpacklo_epi8(
+                    _mm256_add_epi8(idx, _mm256_set1_epi8(4)),
+                    _mm256_add_epi8(idx, _mm256_set1_epi8(5))
+                ),
+                // interleave idx[3:0]+6 = 8*indices[3]+6; ...; 8*indices[0]+6
+                // with       idx[3:0]+7 = 8*indices[3]+7; ...; 8*indices[0]+7
+                // => 8*indices[3]+7; 8*indices[3]+6; ...; 8*indices[0]+7; 8*indices[0]+6
+                _mm256_unpacklo_epi8(
+                    _mm256_add_epi8(idx, _mm256_set1_epi8(6)),
+                    _mm256_add_epi8(idx, _mm256_set1_epi8(7))
+                )
+            )
+        )
+    );
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<32, 16>, SimdParams_<16, 16>)
+{
+    // copy 2nd 64bit word to 3rd, compute 2*idx
+    __m256i idx = _mm256_slli_epi16(_mm256_permute4x64_epi64(_mm256_castsi128_si256(SEQAN_VECTOR_CAST_(const __m128i &, indices)), 0x50), 1);
+
+    // interleave with 2*idx+1 and call shuffle
+    return SEQAN_VECTOR_CAST_(TSimdVector1,
+        _mm256_shuffle_epi8(
+            SEQAN_VECTOR_CAST_(const __m256i &, vector),
+            _mm256_unpacklo_epi8(
+                idx,
+                _mm256_add_epi8(
+                    idx, _mm256_set1_epi8(1)
+                )
+            )
+        )
+    );
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<32, 32>, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector1, seqan_m256_shuffle_epi8(
+        SEQAN_VECTOR_CAST_(const __m256i &, vector),
+        SEQAN_VECTOR_CAST_(const __m256i &, indices)
+    ));
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<32, 16>, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector1, seqan_m256_shuffle_epi16(
+        SEQAN_VECTOR_CAST_(const __m256i &, vector),
+        SEQAN_VECTOR_CAST_(const __m256i &, indices)
+    ));
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<32, 8>, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector1, seqan_m256_shuffle_epi32(
+        SEQAN_VECTOR_CAST_(const __m256i &, vector),
+        SEQAN_VECTOR_CAST_(const __m256i &, indices)
+    ));
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<32, 4>, SimdParams_<32, 32>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector1, seqan_m256_shuffle_epi64(
+        SEQAN_VECTOR_CAST_(const __m256i &, vector),
+        SEQAN_VECTOR_CAST_(const __m256i &, indices)
+    ));
+}
+
+// --------------------------------------------------------------------------
+// _transposeMatrix (256bit)
+// --------------------------------------------------------------------------
+
+// emulate missing _mm256_unpacklo_epi128/_mm256_unpackhi_epi128 instructions
+inline __m256i _mm256_unpacklo_epi128(__m256i const & a, __m256i const & b)
+{
+    return _mm256_permute2x128_si256(a, b, 0x20);
+//    return _mm256_inserti128_si256(a, _mm256_extracti128_si256(b, 0), 1);
+}
+
+inline __m256i _mm256_unpackhi_epi128(__m256i const & a, __m256i const & b)
+{
+    return _mm256_permute2x128_si256(a, b, 0x31);
+//    return _mm256_inserti128_si256(b, _mm256_extracti128_si256(a, 1), 0);
+}
+
+template <typename TSimdVector>
+inline void
+_transposeMatrix(TSimdVector matrix[], SimdMatrixParams_<32, 32, 8>)
+{
+    // we need a look-up table to reverse the lowest 4 bits
+    // in order to place the permute the transposed rows
+    static const unsigned char bitRev[] = { 0, 8, 4,12, 2,10, 6,14, 1, 9, 5,13, 3,11, 7,15,
+                                           16,24,20,28,18,26,22,30,17,25,21,29,19,27,23,31};
+
+    // transpose a 32x32 byte matrix
+    __m256i tmp1[32];
+    for (int i = 0; i < 16; ++i)
+    {
+        tmp1[i]    = _mm256_unpacklo_epi8(
+            SEQAN_VECTOR_CAST_(const __m256i &, matrix[2*i]),
+            SEQAN_VECTOR_CAST_(const __m256i &, matrix[2*i+1])
+        );
+        tmp1[i+16] = _mm256_unpackhi_epi8(
+            SEQAN_VECTOR_CAST_(const __m256i &, matrix[2*i]),
+            SEQAN_VECTOR_CAST_(const __m256i &, matrix[2*i+1])
+        );
+    }
+    __m256i  tmp2[32];
+    for (int i = 0; i < 16; ++i)
+    {
+        tmp2[i]    = _mm256_unpacklo_epi16(tmp1[2*i], tmp1[2*i+1]);
+        tmp2[i+16] = _mm256_unpackhi_epi16(tmp1[2*i], tmp1[2*i+1]);
+    }
+    for (int i = 0; i < 16; ++i)
+    {
+        tmp1[i]    = _mm256_unpacklo_epi32(tmp2[2*i], tmp2[2*i+1]);
+        tmp1[i+16] = _mm256_unpackhi_epi32(tmp2[2*i], tmp2[2*i+1]);
+    }
+    for (int i = 0; i < 16; ++i)
+    {
+        tmp2[i]    = _mm256_unpacklo_epi64(tmp1[2*i], tmp1[2*i+1]);
+        tmp2[i+16] = _mm256_unpackhi_epi64(tmp1[2*i], tmp1[2*i+1]);
+    }
+    for (int i = 0; i < 16; ++i)
+    {
+        matrix[bitRev[i]]    = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_unpacklo_epi128(tmp2[2*i],tmp2[2*i+1]));
+        matrix[bitRev[i+16]] = SEQAN_VECTOR_CAST_(TSimdVector, _mm256_unpackhi_epi128(tmp2[2*i],tmp2[2*i+1]));
+    }
+}
+
+// --------------------------------------------------------------------------
+// Function _testAllZeros (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, int)
+inline _testAllZeros(TSimdVector const & vector, TSimdVector const & mask, SimdParams_<32>)
+{
+    return _mm256_testz_si256(SEQAN_VECTOR_CAST_(const __m256i &, vector),
+                              SEQAN_VECTOR_CAST_(const __m256i &, mask));
+}
+
+// --------------------------------------------------------------------------
+// Function _testAllOnes (256bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline int _testAllOnes(TSimdVector const & vector, SimdParams_<32>)
+{
+    __m256i vec = SEQAN_VECTOR_CAST_(const __m256i &, vector);
+    return _mm256_testc_si256(vec, _mm256_cmpeq_epi32(vec, vec));
+}
+
+} // namespace seqan
+
+#endif // SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_AVX2_H_
diff --git a/include/seqan/simd/simd_base_seqan_impl_sse4.2.h b/include/seqan/simd/simd_base_seqan_impl_sse4.2.h
new file mode 100644
index 0000000..8ceba99
--- /dev/null
+++ b/include/seqan/simd/simd_base_seqan_impl_sse4.2.h
@@ -0,0 +1,978 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: David Weese <david.weese at fu-berlin.de>
+//         René Rahn <rene.rahn at fu-berlin.de>
+//         Stefan Budach <stefan.budach at fu-berlin.de>
+// ==========================================================================
+// generic SIMD interface for SSE3 / AVX2
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_SSE4_2_H_
+#define SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_SSE4_2_H_
+
+namespace seqan {
+
+// SimdParams_<8, 8>: 64bit = 8 elements * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8Char,      char,           8)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8SChar,     signed char,    8)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8UChar,     unsigned char,  8)
+
+// SimdParams_<8, 4>: 64bit = 4 elements * 2 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4Short,     short,          8)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4UShort,    unsigned short, 8)
+
+// SimdParams_<8, 2>: 64bit = 2 elements * 4 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2Int,       int,            8)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2UInt,      unsigned int,   8)
+
+// SimdParams_<16, 16>: 128bit = 16 elements * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16Char,     char,           16)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16SChar,    signed char,    16)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16UChar,    unsigned char,  16)
+
+// SimdParams_<16, 8>: 128bit = 8 elements * 2 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8Short,     short,          16)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8UShort,    unsigned short, 16)
+
+// SimdParams_<16, 4>: 128bit = 4 elements * 4 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4Int,       int,            16)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector4UInt,      unsigned int,   16)
+
+// SimdParams_<16, 2>: 128bit = 2 elements * 8 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2Int64,     int64_t,        16)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector2UInt64,    uint64_t,       16)
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// --------------------------------------------------------------------------
+// _fillVector (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename... TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & x,
+            std::index_sequence<0> const &,
+            SimdParams_<16, 16> const &)
+{
+  vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi8(std::get<0>(x)));
+}
+
+template <typename TSimdVector, typename... TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & x,
+            std::index_sequence<0> const &,
+            SimdParams_<16, 8> const &)
+{
+  vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi16(std::get<0>(x)));
+}
+
+template <typename TSimdVector, typename... TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & x,
+            std::index_sequence<0> const &,
+            SimdParams_<16, 4> const &)
+{
+  vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi32(std::get<0>(x)));
+}
+
+template <typename TSimdVector, typename... TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & x,
+            std::index_sequence<0> const &,
+            SimdParams_<16, 2> const &)
+{
+  vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi64x(std::get<0>(x)));
+}
+
+template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args,
+            std::index_sequence<INDICES...> const &,
+            SimdParams_<16, 16> const &)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_setr_epi8(std::get<INDICES>(args)...));
+}
+
+template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args,
+            std::index_sequence<INDICES...> const &,
+            SimdParams_<16, 8> const &)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_setr_epi16(std::get<INDICES>(args)...));
+}
+
+template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args,
+            std::index_sequence<INDICES...> const &,
+            SimdParams_<16, 4> const &)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_setr_epi32(std::get<INDICES>(args)...));
+}
+
+template <typename TSimdVector, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args,
+            std::index_sequence<INDICES...> const &,
+            SimdParams_<16, 2> const &)
+{
+    // reverse argument list 0, 1 -> 1, 0
+#if defined(COMPILER_LINTEL)
+    // NOTE(marehr): Intel linux fails to reverse argument list and only
+    // _mm_set_epi64x has no reverse equivalent
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_set_epi64x(std::get<1>(args), std::get<0>(args)));
+#else
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_set_epi64x(std::get<sizeof...(INDICES) - 1 - INDICES>(args)...));
+#endif
+}
+
+// --------------------------------------------------------------------------
+// _clearVector (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline void _clearVector(TSimdVector & vector, SimdParams_<16, L>)
+{
+    vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_setzero_si128());
+}
+
+// --------------------------------------------------------------------------
+// _createVector (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TValue>
+inline TSimdVector _createVector(TValue const x, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi8(x));
+}
+
+template <typename TSimdVector, typename TValue>
+inline TSimdVector _createVector(TValue const x, SimdParams_<16, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi16(x));
+}
+
+template <typename TSimdVector, typename TValue>
+inline TSimdVector _createVector(TValue const x, SimdParams_<16, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi32(x));
+}
+
+template <typename TSimdVector, typename TValue>
+inline TSimdVector _createVector(TValue const x, SimdParams_<16, 2>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_set1_epi64x(x));
+}
+
+// --------------------------------------------------------------------------
+// cmpEq (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpeq_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                             SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<16, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpeq_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<16, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpeq_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<16, 2>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpeq_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _cmpGt (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<16, 16, int8_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpgt_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                             SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<16, 16, uint8_t>)
+{
+    // There is no unsigned cmpgt, we reduce it to the signed case.
+    // Note that 0x80 = ~0x7F (prevent overflow messages).
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpgt_epi8(
+                                  _mm_xor_si128(SEQAN_VECTOR_CAST_(const __m128i&, a), _mm_set1_epi8(~0x7F)),
+                                  _mm_xor_si128(SEQAN_VECTOR_CAST_(const __m128i&, b), _mm_set1_epi8(~0x7F))));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<16, 8, int16_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpgt_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<16, 8, uint16_t>)
+{
+    // There is no unsigned cmpgt, we reduce it to the signed case.
+    // Note that 0x8000 = ~0x7FFF (prevent overflow messages).
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpgt_epi16(
+                                  _mm_xor_si128(SEQAN_VECTOR_CAST_(const __m128i&, a), _mm_set1_epi16(~0x7FFF)),
+                                  _mm_xor_si128(SEQAN_VECTOR_CAST_(const __m128i&, b), _mm_set1_epi16(~0x7FFF))));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<16, 4, int32_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpgt_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<16, 4, uint32_t>)
+{
+    // There is no unsigned cmpgt, we reduce it to the signed case.
+    // Note that 0x80000000 = ~0x7FFFFFFF (prevent overflow messages).
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpgt_epi32(
+                                  _mm_xor_si128(SEQAN_VECTOR_CAST_(const __m128i&, a), _mm_set1_epi32(~0x7FFFFFFF)),
+                                  _mm_xor_si128(SEQAN_VECTOR_CAST_(const __m128i&, b), _mm_set1_epi32(~0x7FFFFFFF))));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<16, 2, int64_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpgt_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<16, 2, uint64_t>)
+{
+    // There is no unsigned cmpgt, we reduce it to the signed case.
+    // Note that 0x8000000000000000ul = ~0x7FFFFFFFFFFFFFFFul (prevent overflow messages).
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpgt_epi64(
+                                  _mm_xor_si128(SEQAN_VECTOR_CAST_(const __m128i&, a) ,_mm_set1_epi64x(~0x7FFFFFFFFFFFFFFFul)),
+                                  _mm_xor_si128(SEQAN_VECTOR_CAST_(const __m128i&, b), _mm_set1_epi64x(~0x7FFFFFFFFFFFFFFFul))));
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseOr (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _bitwiseOr(TSimdVector & a, TSimdVector & b, SimdParams_<16, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_or_si128(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseAnd (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _bitwiseAnd(TSimdVector & a, TSimdVector & b, SimdParams_<16, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_and_si128(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseAndNot (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _bitwiseAndNot(TSimdVector & a, TSimdVector & b, SimdParams_<16, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_andnot_si128(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                               SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseNot (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseNot(TSimdVector & a, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpeq_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                             _mm_setzero_si128()));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseNot(TSimdVector & a, SimdParams_<16, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpeq_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              _mm_setzero_si128()));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseNot(TSimdVector & a, SimdParams_<16, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpeq_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              _mm_setzero_si128()));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _bitwiseNot(TSimdVector & a, SimdParams_<16, 2>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_cmpeq_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              _mm_setzero_si128()));
+}
+
+// --------------------------------------------------------------------------
+// _divide (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _divide(TSimdVector & a, int b, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_div_epi8(a, _mm_set1_epi8(b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _divide(TSimdVector & a, int b, SimdParams_<16, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_div_epi16(a, _mm_set1_epi16(b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _divide(TSimdVector & a, int b, SimdParams_<16, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_div_epi32(a, _mm_set1_epi32(b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _divide(TSimdVector & a, int b, SimdParams_<16, 2>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_div_epi64(a, _mm_set1_epi64x(b)));
+}
+
+// --------------------------------------------------------------------------
+// _add (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _add(TSimdVector & a, TSimdVector & b, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_add_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _add(TSimdVector & a, TSimdVector & b, SimdParams_<16, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_add_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _add(TSimdVector & a, TSimdVector & b, SimdParams_<16, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_add_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _add(TSimdVector & a, TSimdVector & b, SimdParams_<16, 2>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_add_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _sub (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _sub(TSimdVector & a, TSimdVector & b, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_sub_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _sub(TSimdVector & a, TSimdVector & b, SimdParams_<16, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_sub_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _sub(TSimdVector & a, TSimdVector & b, SimdParams_<16, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_sub_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _sub(TSimdVector & a, TSimdVector & b, SimdParams_<16, 2>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_sub_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+// --------------------------------------------------------------------------
+// _mult (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _mult(TSimdVector & a, TSimdVector &/*b*/, SimdParams_<16, 16>)
+{
+    SEQAN_ASSERT_FAIL("SSE intrinsics for multiplying 8 bit values not implemented!");
+    return a;
+}
+
+template <typename TSimdVector>
+inline TSimdVector _mult(TSimdVector & a, TSimdVector & b, SimdParams_<16, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_mullo_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _mult(TSimdVector & a, TSimdVector & b, SimdParams_<16, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_mullo_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _mult(TSimdVector & a, TSimdVector &/*b*/, SimdParams_<16, 2>)
+{
+    SEQAN_ASSERT_FAIL("SSE intrinsics for multiplying 64 bit values not implemented!");
+    return a;
+}
+
+// --------------------------------------------------------------------------
+// _max (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<16, 16, int8_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_max_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<16, 16, uint8_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_max_epu8(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                           SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<16, 8, int16_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_max_epi16(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<16, 8, uint16_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_max_epu16(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<16, 4, int32_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_max_epi32(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<16, 4, uint32_t>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_max_epu32(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<16, 2, int64_t>)
+{
+#if defined(__AVX512VL__)
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_max_epi64(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+#else // defined(__AVX512VL__)
+    return blend(b, a, cmpGt(a, b));
+#endif // defined(__AVX512VL__)
+}
+
+template <typename TSimdVector>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<16, 2, uint64_t>)
+{
+#if defined(__AVX512VL__)
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_max_epu64(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                            SEQAN_VECTOR_CAST_(const __m128i&, b)));
+#else // defined(__AVX512VL__)
+    return blend(b, a, cmpGt(a, b));
+#endif // defined(__AVX512VL__)
+}
+
+// --------------------------------------------------------------------------
+// _blend (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TSimdVectorMask, int L>
+inline TSimdVector _blend(TSimdVector const & a, TSimdVector const & b, TSimdVectorMask const & mask, SimdParams_<16, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector,
+                              _mm_blendv_epi8(SEQAN_VECTOR_CAST_(const __m128i&, a),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, b),
+                                              SEQAN_VECTOR_CAST_(const __m128i&, mask)));
+}
+
+// --------------------------------------------------------------------------
+// _storeu (128bit)
+// --------------------------------------------------------------------------
+
+template <typename T, typename TSimdVector, int L>
+inline void _storeu(T * memAddr, TSimdVector & vec, SimdParams_<16, L>)
+{
+    _mm_storeu_si128((__m128i*)memAddr, reinterpret_cast<const __m128i &>(vec));
+}
+
+// ----------------------------------------------------------------------------
+// Function _load() 128bit
+// ----------------------------------------------------------------------------
+
+template <typename TSimdVector, typename T, int L>
+inline TSimdVector _load(T const * memAddr, SimdParams_<16, L>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_load_si128((__m128i const *) memAddr));
+}
+
+// --------------------------------------------------------------------------
+// _shiftRightLogical (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_srli_epi16(SEQAN_VECTOR_CAST_(const __m128i &, vector), imm) & _mm_set1_epi8(0xff >> imm));
+}
+template <typename TSimdVector>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<16, 8>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_srli_epi16(SEQAN_VECTOR_CAST_(const __m128i &, vector), imm));
+}
+template <typename TSimdVector>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<16, 4>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_srli_epi32(SEQAN_VECTOR_CAST_(const __m128i &, vector), imm));
+}
+template <typename TSimdVector>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<16, 2>)
+{
+    return SEQAN_VECTOR_CAST_(TSimdVector, _mm_srli_epi64(SEQAN_VECTOR_CAST_(const __m128i &, vector), imm));
+}
+
+// --------------------------------------------------------------------------
+// _gather (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TValue, typename TSimdVector, typename TSize, TSize SCALE, typename TSimdParams>
+inline TSimdVector
+_gather(TValue const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & /*scale*/,
+        TSimdParams)
+{
+    TSimdVector ret;
+    for (auto i = 0u; i < LENGTH<TSimdVector>::VALUE; ++i)
+    {
+        ret[i] = memAddr[idx[i]];
+    }
+    return ret;
+}
+
+// --------------------------------------------------------------------------
+// _shuffleVector (128bit)
+// --------------------------------------------------------------------------
+
+inline __m128i
+seqan_mm_shuffle_epi16(const __m128i a, const __m128i b)
+{
+    // multiply by 2
+    __m128i idx = _mm_slli_epi16(b, 1);
+    return _mm_shuffle_epi8(
+        a,
+        // interleave idx[7:0]   = 2*indices[7],   ..., 2*indices[0]
+        // with       idx[7:0]+1 = 2*indices[7]+1, ..., 2*indices[0]+1
+        // => 2*indices[7]+1, 2*indices[7], ..., 2*indices[0]+1, 2*indices[0]
+        _mm_unpacklo_epi8(
+            idx,
+            _mm_add_epi8(idx, _mm_set1_epi8(1))
+        )
+    );
+}
+
+inline __m128i
+seqan_mm_shuffle_epi32(const __m128i a, const __m128i b)
+{
+    // multiply by 4
+    __m128i idx = _mm_slli_epi16(b, 2);
+    return _mm_shuffle_epi8(
+        a,
+        // interleave 4*indices[3]+1, 4*indices[3]+0; ..., 4*indices[0]+1, 4*indices[0]+0
+        // with       4*indices[3]+3, 4*indices[3]+2; ..., 4*indices[0]+3, 4*indices[0]+2
+        // => 4*indices[3]+3, 4*indices[3]+2; 4*indices[3]+1, 4*indices[3]+0;
+        //    ...
+        //    4*indices[0]+3, 4*indices[0]+2; 4*indices[0]+1, 4*indices[0]+0
+        _mm_unpacklo_epi16(
+            // interleave idx[3:0]+0 = 4*indices[3]+0; ...; 4*indices[0]+0
+            // with       idx[3:0]+1 = 4*indices[3]+1; ...; 4*indices[0]+1
+            // => 4*indices[3]+1; 4*indices[3]+0; ...; 4*indices[0]+1; 4*indices[0]+0
+            _mm_unpacklo_epi8(
+                idx,
+                _mm_add_epi8(idx, _mm_set1_epi8(1))
+            ),
+            // interleave idx[3:0]+2 = 4*indices[3]+2; ...; 4*indices[0]+2
+            // with       idx[3:0]+3 = 4*indices[3]+3; ...; 4*indices[0]+3
+            // => 4*indices[3]+3; 4*indices[3]+2; ...; 4*indices[0]+3; 4*indices[0]+2
+            _mm_unpacklo_epi8(
+                _mm_add_epi8(idx, _mm_set1_epi8(2)),
+                _mm_add_epi8(idx, _mm_set1_epi8(3))
+            )
+    ));
+}
+
+inline __m128i
+seqan_mm_shuffle_epi64(const __m128i a, const __m128i b)
+{
+    // multiply by 8
+    __m128i idx = _mm_slli_epi16(b, 3);
+    return _mm_shuffle_epi8(
+        a,
+        _mm_unpacklo_epi32(
+            // interleave 8*indices[1]+1, 8*indices[1]+0; ..., 8*indices[0]+1, 8*indices[0]+0
+            // with       8*indices[1]+3, 8*indices[1]+2; ..., 8*indices[0]+3, 8*indices[0]+2
+            // => 8*indices[1]+3, 8*indices[1]+2; 8*indices[1]+1, 8*indices[1]+0;
+            //    ...
+            //    8*indices[0]+3, 8*indices[0]+2; 8*indices[0]+1, 8*indices[0]+0
+            _mm_unpacklo_epi16(
+                // interleave idx[1:0]+0 = 8*indices[1]+0; ...; 8*indices[0]+0
+                // with       idx[1:0]+1 = 8*indices[1]+1; ...; 8*indices[0]+1
+                // => 8*indices[1]+1; 8*indices[1]+0; ...; 8*indices[0]+1; 8*indices[0]+0
+                _mm_unpacklo_epi8(
+                    idx,
+                    _mm_add_epi8(idx, _mm_set1_epi8(1))
+                ),
+                // interleave idx[1:0]+2 = 8*indices[1]+2; ...; 8*indices[0]+2
+                // with       idx[1:0]+3 = 8*indices[1]+3; ...; 8*indices[0]+3
+                // => 8*indices[1]+3; 8*indices[1]+2; ...; 8*indices[0]+3; 8*indices[0]+2
+                _mm_unpacklo_epi8(
+                    _mm_add_epi8(idx, _mm_set1_epi8(2)),
+                    _mm_add_epi8(idx, _mm_set1_epi8(3))
+                )
+            ),
+            // interleave 8*indices[1]+5, 8*indices[1]+4; ..., 8*indices[0]+5, 8*indices[0]+4
+            // with       8*indices[1]+7, 8*indices[1]+6; ..., 8*indices[0]+7, 8*indices[0]+6
+            // => 8*indices[1]+7, 8*indices[1]+6; 8*indices[1]+5, 8*indices[1]+4;
+            //    ...
+            //    8*indices[0]+7, 8*indices[0]+6; 8*indices[0]+5, 8*indices[0]+4
+            _mm_unpacklo_epi16(
+                // interleave idx[1:0]+4 = 8*indices[1]+4; ...; 8*indices[0]+4
+                // with       idx[1:0]+5 = 8*indices[1]+5; ...; 8*indices[0]+5
+                // => 8*indices[1]+5; 8*indices[1]+4; ...; 8*indices[0]+5; 8*indices[0]+4
+                _mm_unpacklo_epi8(
+                    _mm_add_epi8(idx, _mm_set1_epi8(4)),
+                    _mm_add_epi8(idx, _mm_set1_epi8(5))
+                ),
+                // interleave idx[1:0]+6 = 8*indices[1]+6; ...; 8*indices[0]+6
+                // with       idx[1:0]+7 = 8*indices[1]+7; ...; 8*indices[0]+7
+                // => 8*indices[1]+7; 8*indices[1]+6; ...; 8*indices[0]+7; 8*indices[0]+6
+                _mm_unpacklo_epi8(
+                    _mm_add_epi8(idx, _mm_set1_epi8(6)),
+                    _mm_add_epi8(idx, _mm_set1_epi8(7))
+                )
+            )
+        )
+    );
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+[[deprecated("Here be dragons")]]
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<16, 8>, SimdParams_<8, 8>)
+{
+#if SEQAN_IS_32_BIT
+    __m128i idx = _mm_slli_epi16(
+        _mm_unpacklo_epi32(
+            _mm_cvtsi32_si128(reinterpret_cast<const uint32_t &>(indices)),
+            _mm_cvtsi32_si128(reinterpret_cast<const uint64_t &>(indices) >> 32)
+        ),
+        1
+    );
+#else
+    __m128i idx = _mm_slli_epi16(_mm_cvtsi64_si128(reinterpret_cast<const uint64_t &>(indices)), 1);
+#endif  // SEQAN_IS_32_BIT
+    return SEQAN_VECTOR_CAST_(TSimdVector1,
+        _mm_shuffle_epi8(
+            SEQAN_VECTOR_CAST_(const __m128i &, vector),
+            _mm_unpacklo_epi8(idx, _mm_add_epi8(idx, _mm_set1_epi8(1)))
+        ));
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<16, 16>, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector1,
+        _mm_shuffle_epi8(
+            SEQAN_VECTOR_CAST_(const __m128i &, vector),
+            SEQAN_VECTOR_CAST_(const __m128i &, indices)
+    ));
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<16, 8>, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector1,
+        seqan_mm_shuffle_epi16(
+            SEQAN_VECTOR_CAST_(const __m128i &, vector),
+            SEQAN_VECTOR_CAST_(const __m128i &, indices)
+    ));
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<16, 4>, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector1,
+        seqan_mm_shuffle_epi32(
+            SEQAN_VECTOR_CAST_(const __m128i &, vector),
+            SEQAN_VECTOR_CAST_(const __m128i &, indices)
+    ));
+}
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<16, 2>, SimdParams_<16, 16>)
+{
+    return SEQAN_VECTOR_CAST_(
+        TSimdVector1,
+        seqan_mm_shuffle_epi64(
+            SEQAN_VECTOR_CAST_(const __m128i &, vector),
+            SEQAN_VECTOR_CAST_(const __m128i &, indices)
+    ));
+}
+
+// --------------------------------------------------------------------------
+// _transposeMatrix (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline void
+_transposeMatrix(TSimdVector matrix[], SimdMatrixParams_<8, 8, 8>)
+{
+    // we need a look-up table to reverse the lowest 4 bits
+    // in order to place the permute the transposed rows
+    static const unsigned char bitRev[] = {0,4,2,6,1,5,3,7};
+
+    // transpose a 8x8 byte matrix
+    __m64 tmp1[8];
+    for (int i = 0; i < 4; ++i)
+    {
+        tmp1[i]   = _mm_unpacklo_pi8(SEQAN_VECTOR_CAST_(const __m64 &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m64 &, matrix[2*i+1]));
+        tmp1[i+4] = _mm_unpackhi_pi8(SEQAN_VECTOR_CAST_(const __m64 &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m64 &, matrix[2*i+1]));
+    }
+    __m64 tmp2[8];
+    for (int i = 0; i < 4; ++i)
+    {
+        tmp2[i]   = _mm_unpacklo_pi16(tmp1[2*i], tmp1[2*i+1]);
+        tmp2[i+4] = _mm_unpackhi_pi16(tmp1[2*i], tmp1[2*i+1]);
+    }
+    for (int i = 0; i < 4; ++i)
+    {
+        matrix[bitRev[i]]   = SEQAN_VECTOR_CAST_(TSimdVector, _mm_unpacklo_pi32(tmp2[2*i], tmp2[2*i+1]));
+        matrix[bitRev[i+4]] = SEQAN_VECTOR_CAST_(TSimdVector, _mm_unpackhi_pi32(tmp2[2*i], tmp2[2*i+1]));
+    }
+}
+
+template <typename TSimdVector>
+inline void
+_transposeMatrix(TSimdVector matrix[], SimdMatrixParams_<16, 16, 8>)
+{
+    // we need a look-up table to reverse the lowest 4 bits
+    // in order to place the permute the transposed rows
+    static const unsigned char bitRev[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
+
+    // transpose a 16x16 byte matrix
+    //
+    // matrix =
+    // A0 A1 A2 ... Ae Af
+    // B0 B1 B2 ... Be Bf
+    // ...
+    // P0 P1 P2 ... Pe Pf
+    __m128i tmp1[16];
+    for (int i = 0; i < 8; ++i)
+    {
+        tmp1[i]   = _mm_unpacklo_epi8(SEQAN_VECTOR_CAST_(const __m128i &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m128i &, matrix[2*i+1]));
+        tmp1[i+8] = _mm_unpackhi_epi8(SEQAN_VECTOR_CAST_(const __m128i &, matrix[2*i]), SEQAN_VECTOR_CAST_(const __m128i &, matrix[2*i+1]));
+    }
+    // tmp1[0]  = A0 B0 A1 B1 ... A7 B7
+    // tmp1[1]  = C0 D0 C1 D1 ... C7 D7
+    // ...
+    // tmp1[7]  = O0 P0 O1 P1 ... O7 P7
+    // tmp1[8]  = A8 B8 A9 B9 ... Af Bf
+    // ...
+    // tmp1[15] = O8 P8 O9 P9 ... Of Pf
+    __m128i tmp2[16];
+    for (int i = 0; i < 8; ++i)
+    {
+        tmp2[i]   = _mm_unpacklo_epi16(tmp1[2*i], tmp1[2*i+1]);
+        tmp2[i+8] = _mm_unpackhi_epi16(tmp1[2*i], tmp1[2*i+1]);
+    }
+    // tmp2[0]  = A0 B0 C0 D0 ... A3 B3 C3 D3
+    // tmp2[1]  = E0 F0 G0 H0 ... E3 F3 G3 H3
+    // ...
+    // tmp2[3]  = M0 N0 O0 P0 ... M3 N3 O3 P3
+    // tmp2[4]  = A8 B8 C8 D8 ... Ab Bb Cb Db
+    // ...
+    // tmp2[7]  = M8 N8 O8 P8 ... Mb Nb Ob Pb
+    // tmp2[8]  = A4 B4 C4 D4 ... A7 B7 C7 D7
+    // ..
+    // tmp2[12] = Ac Bc Cc Dc ... Af Bf Cf Df
+    // ...
+    // tmp2[15] = Mc Nc Oc Pc ... Mf Nf Of Pf
+    for (int i = 0; i < 8; ++i)
+    {
+        tmp1[i]   = _mm_unpacklo_epi32(tmp2[2*i], tmp2[2*i+1]);
+        tmp1[i+8] = _mm_unpackhi_epi32(tmp2[2*i], tmp2[2*i+1]);
+    }
+    // tmp1[0]  = A0 B0 .... H0 A1 B1 .... H1
+    // tmp1[1]  = I0 J0 .... P0 I1 J1 .... P1
+    // ...
+    // tmp1[4]  = A0 B0 .... H0 A1 B1 .... H1
+    // tmp1[1]  = I0 J0 .... P0 I1 J1 .... P1
+    for (int i = 0; i < 8; ++i)
+    {
+        matrix[bitRev[i]]   = SEQAN_VECTOR_CAST_(TSimdVector, _mm_unpacklo_epi64(tmp1[2*i], tmp1[2*i+1]));
+        matrix[bitRev[i+8]] = SEQAN_VECTOR_CAST_(TSimdVector, _mm_unpackhi_epi64(tmp1[2*i], tmp1[2*i+1]));
+    }
+}
+
+// --------------------------------------------------------------------------
+// Function _testAllZeros (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, int)
+inline _testAllZeros(TSimdVector const & vector, TSimdVector const & mask, SimdParams_<16>)
+{
+    return _mm_testz_si128(vector, mask);
+}
+
+// --------------------------------------------------------------------------
+// Function _testAllOnes (128bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline
+SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, int)
+_testAllOnes(TSimdVector const & vector, SimdParams_<16>)
+{
+    return _mm_test_all_ones(SEQAN_VECTOR_CAST_(const __m128i &, vector));
+}
+
+} // namespace seqan
+
+#endif // SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_SSE4_2_H_
diff --git a/include/seqan/simd/simd_base_seqan_interface.h b/include/seqan/simd/simd_base_seqan_interface.h
new file mode 100644
index 0000000..92114c9
--- /dev/null
+++ b/include/seqan/simd/simd_base_seqan_interface.h
@@ -0,0 +1,389 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: David Weese <david.weese at fu-berlin.de>
+//         René Rahn <rene.rahn at fu-berlin.de>
+//         Stefan Budach <stefan.budach at fu-berlin.de>
+// ==========================================================================
+// generic SIMD interface for SSE3 / AVX2
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_INTERFACE_H_
+#define SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_INTERFACE_H_
+
+namespace seqan {
+
+template <typename TSimdVector>
+struct SimdSwizzleVectorImpl<TSimdVector, True>
+{
+    typedef typename SimdVector<uint8_t, sizeof(TSimdVector)>::Type Type;
+};
+
+// ============================================================================
+//
+// INTERFACE FUNCTIONS
+// - these should be used in the actual code, they will call one of the wrapper
+//   functions defined above based on the vector type
+//
+// ============================================================================
+
+// --------------------------------------------------------------------------
+// Function transpose()
+// --------------------------------------------------------------------------
+
+template <int ROWS, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+transpose(TSimdVector matrix[ROWS])
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    _transposeMatrix(matrix, SimdMatrixParams_<ROWS, LENGTH<TSimdVector>::VALUE, BitsPerValue<TValue>::VALUE>());
+}
+
+// --------------------------------------------------------------------------
+// Function clearVector()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+clearVector(TSimdVector & vector)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    _clearVector(vector, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function createVector()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TValue>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+createVector(TValue const x)
+{
+    typedef typename Value<TSimdVector>::Type TIVal;
+    return _createVector<TSimdVector>(x, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TIVal)>());
+}
+
+// --------------------------------------------------------------------------
+// Function fillVector()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename ...TValue>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+fillVector(TSimdVector & vector, TValue const... args)
+{
+    // On clang (<= 4.0)
+    // std::make_tuple(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) reaches the
+    // template recursion limit of 256 (e.g. -ftemplate-depth=256 is default)
+    //
+    // See same issue asked on http://stackoverflow.com/q/23374953
+    // See also discussion to increase -ftemplate-depth to 1024 by default in
+    // clang https://llvm.org/bugs/show_bug.cgi?id=18417
+    typedef typename Value<TSimdVector>::Type TIVal;
+    _fillVector(vector, std::make_tuple(args...),
+                std::make_index_sequence<sizeof...(args)>{},
+                SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TIVal)>());
+}
+
+// --------------------------------------------------------------------------
+// Function cmpEq()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+cmpEq (TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _cmpEq(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator==()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator==(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _cmpEq(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function operatorGt()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+cmpGt (TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _cmpGt(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue), TValue>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator>()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator>(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _cmpGt(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function max()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+max(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _max(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue), TValue>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator|()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator|(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _bitwiseOr(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator|=()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector &)
+operator|=(TSimdVector & a, TSimdVector const & b)
+{
+    a = a | b;
+    return a;
+}
+
+// --------------------------------------------------------------------------
+// Function operator&()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator&(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _bitwiseAnd(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator&=()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector &)
+operator&=(TSimdVector & a, TSimdVector const & b)
+{
+    a = a & b;
+    return a;
+}
+
+// --------------------------------------------------------------------------
+// Function operator~()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator~(TSimdVector const & a)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _bitwiseNot(a, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator+()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator+(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _add(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator-()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator-(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _sub(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator*()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator*(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _mult(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function operator/()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator/(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _div(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function andNot
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+andNot(TSimdVector const & a, TSimdVector const & b)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _bitwiseAndNot(a, b, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function shiftRightLogical()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+shiftRightLogical(TSimdVector const & vector, const int imm)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _shiftRightLogical(vector, imm, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function blend()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TSimdVectorMask>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+blend(TSimdVector const & a, TSimdVector const & b, TSimdVectorMask const & mask)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _blend(a, b, mask, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function storeu()
+// --------------------------------------------------------------------------
+
+template <typename T, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+storeu(T * memAddr, TSimdVector const & vec)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    _storeu(memAddr, vec, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function load()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename T>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+load(T const * memAddr)
+{
+    typedef typename Value<TSimdVector>::Type TValue;
+    return _load<TSimdVector>(memAddr, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function gather()
+// --------------------------------------------------------------------------
+
+template <typename TValue, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+gather(TValue const * memAddr, TSimdVector const & idx)
+{
+    typedef typename Value<TSimdVector>::Type TInnerValue;
+    return _gather(memAddr, idx, std::integral_constant<size_t, sizeof(TValue)>(), SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TInnerValue)>());
+}
+
+// --------------------------------------------------------------------------
+// Function shuffleVector()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector1> >, TSimdVector1)
+shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices)
+{
+    typedef typename Value<TSimdVector1>::Type TValue1;
+    typedef typename Value<TSimdVector2>::Type TValue2;
+    return _shuffleVector(
+                vector,
+                indices,
+                SimdParams_<sizeof(TSimdVector1), sizeof(TSimdVector1) / sizeof(TValue1)>(),
+                SimdParams_<sizeof(TSimdVector2), sizeof(TSimdVector2) / sizeof(TValue2)>());
+}
+
+// --------------------------------------------------------------------------
+// Function print()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, std::ostream &)
+print(std::ostream & stream, TSimdVector const & vector)
+{
+    stream << '<';
+    for (int i = 0; i < LENGTH<TSimdVector>::VALUE; ++i)
+    stream << '\t' << vector[i];
+    stream << "\t>\n";
+    return stream;
+}
+
+} // namespace seqan
+
+#endif // SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_INTERFACE_H_
diff --git a/include/seqan/simd/simd_base_umesimd_impl.h b/include/seqan/simd/simd_base_umesimd_impl.h
new file mode 100644
index 0000000..ea8f632
--- /dev/null
+++ b/include/seqan/simd/simd_base_umesimd_impl.h
@@ -0,0 +1,602 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: Marcel Ehrhardt <marcel.ehrhardt at fu-berlin.de>
+// ==========================================================================
+// SIMD implementation of umesimd
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_UMESIMD_IMPL_H_
+#define SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_UMESIMD_IMPL_H_
+
+#include "umesimd/UMESimd.h"
+
+namespace seqan
+{
+
+template <typename TSimdVector>
+struct SimdSwizzleVectorImpl<TSimdVector, True>
+{
+    using Type = typename UME::SIMD::SIMDTraits<TSimdVector>::SWIZZLE_T;
+};
+
+template <typename TValue, int LENGTH>
+struct SimdVector
+{
+    typedef UME::SIMD::SIMDVec<TValue, LENGTH> Type;
+};
+
+// // 64 bit
+// using SimdVector8Char   = UME::SIMD::SIMDVec<char, 8>;
+using SimdVector8SChar  = UME::SIMD::SIMDVec<signed char, 8>;
+using SimdVector8UChar  = UME::SIMD::SIMDVec<unsigned char, 8>;
+using SimdVector4Short  = UME::SIMD::SIMDVec<short, 4>;
+using SimdVector4UShort = UME::SIMD::SIMDVec<unsigned short, 4>;
+using SimdVector2Int    = UME::SIMD::SIMDVec<int, 2>;
+using SimdVector2UInt   = UME::SIMD::SIMDVec<unsigned int, 2>;
+
+// 128 bit
+// using SimdVector16Char  = UME::SIMD::SIMDVec<char, 16>;
+using SimdVector16SChar = UME::SIMD::SIMDVec<signed char, 16>;
+using SimdVector16UChar = UME::SIMD::SIMDVec<unsigned char, 16>;
+using SimdVector8Short  = UME::SIMD::SIMDVec<short, 8>;
+using SimdVector8UShort = UME::SIMD::SIMDVec<unsigned short, 8>;
+using SimdVector4Int    = UME::SIMD::SIMDVec<int, 4>;
+using SimdVector4UInt   = UME::SIMD::SIMDVec<unsigned int, 4>;
+using SimdVector2Int64  = UME::SIMD::SIMDVec<int64_t, 2>;
+using SimdVector2UInt64 = UME::SIMD::SIMDVec<uint64_t, 2>;
+
+// 256 bit
+// using SimdVector32Char   = UME::SIMD::SIMDVec<char, 32>;
+using SimdVector32SChar  = UME::SIMD::SIMDVec<signed char, 32>;
+using SimdVector32UChar  = UME::SIMD::SIMDVec<unsigned char, 32>;
+using SimdVector16Short  = UME::SIMD::SIMDVec<short, 16>;
+using SimdVector16UShort = UME::SIMD::SIMDVec<unsigned short, 16>;
+using SimdVector8Int     = UME::SIMD::SIMDVec<int, 8>;
+using SimdVector8UInt    = UME::SIMD::SIMDVec<unsigned int, 8>;
+using SimdVector4Int64   = UME::SIMD::SIMDVec<int64_t, 4>;
+using SimdVector4UInt64  = UME::SIMD::SIMDVec<uint64_t, 4>;
+
+// 512 bit
+// using SimdVector64Char   = UME::SIMD::SIMDVec<char, 64>;
+using SimdVector64SChar  = UME::SIMD::SIMDVec<signed char, 64>;
+using SimdVector64UChar  = UME::SIMD::SIMDVec<unsigned char, 64>;
+using SimdVector32Short  = UME::SIMD::SIMDVec<short, 32>;
+using SimdVector32UShort = UME::SIMD::SIMDVec<unsigned short, 32>;
+using SimdVector16Int    = UME::SIMD::SIMDVec<int, 16>;
+using SimdVector16UInt   = UME::SIMD::SIMDVec<unsigned int, 16>;
+using SimdVector8Int64   = UME::SIMD::SIMDVec<int64_t, 8>;
+using SimdVector8UInt64  = UME::SIMD::SIMDVec<uint64_t, 8>;
+
+// ============================================================================
+// SIMDSwizzle
+// ============================================================================
+
+template <uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDSwizzle<LENGTH>),       (SimdVectorConcept));
+
+template <uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDSwizzle<LENGTH> const), (SimdVectorConcept));
+
+template <uint32_t LENGTH>
+struct Value<UME::SIMD::SIMDSwizzle<LENGTH> >
+{
+    typedef uint32_t Type;
+};
+
+template <uint32_t LENGTH_>
+struct LENGTH<UME::SIMD::SIMDSwizzle<LENGTH_> >
+{
+    enum { VALUE = LENGTH_ };
+};
+
+template <uint32_t LENGTH, typename TPosition>
+inline typename Value<UME::SIMD::SIMDSwizzle<LENGTH> >::Type
+getValue(UME::SIMD::SIMDSwizzle<LENGTH> const & vector, TPosition const pos)
+{
+    return vector[pos];
+}
+
+template <uint32_t LENGTH, typename TPosition>
+inline typename Value<UME::SIMD::SIMDSwizzle<LENGTH> >::Type
+value(UME::SIMD::SIMDSwizzle<LENGTH> const & vector, TPosition const pos)
+{
+    return vector[pos];
+}
+
+template <uint32_t LENGTH, typename TPosition, typename TValue2>
+inline void
+assignValue(UME::SIMD::SIMDSwizzle<LENGTH> &vector, TPosition const pos, TValue2 const value)
+{
+    vector.insert(pos, value);
+}
+
+// ============================================================================
+// SIMDVec_u
+// ============================================================================
+
+template <typename TValue, uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDVec_u<TValue, LENGTH>),       (SimdVectorConcept));
+
+template <typename TValue, uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDVec_u<TValue, LENGTH> const), (SimdVectorConcept));
+
+template <typename TValue, uint32_t LENGTH>
+struct Value<UME::SIMD::SIMDVec_u<TValue, LENGTH> >
+{
+    typedef TValue Type;
+};
+
+template <typename TValue, uint32_t LENGTH_>
+struct LENGTH<UME::SIMD::SIMDVec_u<TValue, LENGTH_> > {
+    enum { VALUE = LENGTH_ };
+};
+
+template <typename TValue, uint32_t LENGTH, typename TPosition>
+inline TValue
+getValue(UME::SIMD::SIMDVec_u<TValue, LENGTH> const & vector, TPosition const pos)
+{
+    return vector[pos];
+}
+
+template <typename TValue, uint32_t LENGTH, typename TPosition>
+inline TValue
+value(UME::SIMD::SIMDVec_u<TValue, LENGTH> const & vector, TPosition const pos)
+{
+
+    return vector[pos];
+}
+
+template <typename TValue, uint32_t LENGTH, typename TPosition, typename TValue2>
+inline void
+assignValue(UME::SIMD::SIMDVec_u<TValue, LENGTH> &vector, TPosition const pos, TValue2 const value)
+{
+    vector[pos] = value;
+}
+
+// ============================================================================
+// SIMDVec_i
+// ============================================================================
+
+template <typename TValue, uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDVec_i<TValue, LENGTH>),       (SimdVectorConcept));
+
+template <typename TValue, uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDVec_i<TValue, LENGTH> const), (SimdVectorConcept));
+
+template <typename TValue, uint32_t LENGTH>
+struct Value<UME::SIMD::SIMDVec_i<TValue, LENGTH> >
+{
+    typedef TValue Type;
+};
+
+template <typename TValue, uint32_t LENGTH_>
+struct LENGTH<UME::SIMD::SIMDVec_i<TValue, LENGTH_> > {
+    enum { VALUE = LENGTH_ };
+};
+
+template <typename TValue, uint32_t LENGTH, typename TPosition>
+inline TValue
+getValue(UME::SIMD::SIMDVec_i<TValue, LENGTH> const & vector, TPosition const pos)
+{
+    return vector[pos];
+}
+
+template <typename TValue, uint32_t LENGTH, typename TPosition>
+inline TValue
+value(UME::SIMD::SIMDVec_i<TValue, LENGTH> const & vector, TPosition const pos)
+{
+
+    return vector[pos];
+}
+
+template <typename TValue, uint32_t LENGTH, typename TPosition, typename TValue2>
+inline void
+assignValue(UME::SIMD::SIMDVec_i<TValue, LENGTH> &vector, TPosition const pos, TValue2 const value)
+{
+    vector[pos] = value;
+}
+
+// ============================================================================
+// SIMDVec_f
+// ============================================================================
+
+template <typename TValue, uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDVec_f<TValue, LENGTH>),       (SimdVectorConcept));
+
+template <typename TValue, uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDVec_f<TValue, LENGTH> const), (SimdVectorConcept));
+
+template <typename TValue, uint32_t LENGTH>
+struct Value<UME::SIMD::SIMDVec_f<TValue, LENGTH> >
+{
+    typedef TValue Type;
+};
+
+template <typename TValue, uint32_t LENGTH_>
+struct LENGTH<UME::SIMD::SIMDVec_f<TValue, LENGTH_> > {
+    enum { VALUE = LENGTH_ };
+};
+
+template <typename TValue, uint32_t LENGTH, typename TPosition>
+inline TValue
+getValue(UME::SIMD::SIMDVec_f<TValue, LENGTH> const & vector, TPosition const pos)
+{
+    return vector[pos];
+}
+
+template <typename TValue, uint32_t LENGTH, typename TPosition>
+inline TValue
+value(UME::SIMD::SIMDVec_f<TValue, LENGTH> const & vector, TPosition const pos)
+{
+
+    return vector[pos];
+}
+
+template <typename TValue, uint32_t LENGTH, typename TPosition, typename TValue2>
+inline void
+assignValue(UME::SIMD::SIMDVec_f<TValue, LENGTH> &vector, TPosition const pos, TValue2 const value)
+{
+    vector[pos] = value;
+}
+
+} // namespace seqan
+
+namespace UME
+{
+namespace SIMD
+{
+    template <typename TStream,
+              typename TVector, typename TScalar>
+    inline TStream & operator<<(TStream & stream,
+               IntermediateIndex<TVector, TScalar> const & pInterIndex)
+    {
+        stream << static_cast<TScalar>(pInterIndex);
+        return stream;
+    }
+}
+}
+
+namespace seqan
+{
+
+// --------------------------------------------------------------------------
+// Function clearVector()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+clearVector(TSimdVector & vector)
+{
+    vector = 0;
+}
+
+
+// --------------------------------------------------------------------------
+// Function createVector()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TValue>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+createVector(TValue const x)
+{
+    return TSimdVector(x);
+}
+
+// --------------------------------------------------------------------------
+// Function fillVector()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename ...TValue>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+fillVector(TSimdVector & vector, TValue const... args)
+{
+    vector = TSimdVector(args...);
+}
+
+// --------------------------------------------------------------------------
+// Function cmpEq()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+cmpEq (TSimdVector const & a, TSimdVector const & b)
+{
+    using TValue = typename UME::SIMD::SIMDTraits<TSimdVector>::SCALAR_T;
+    TSimdVector retval(0);
+    retval.assign(a.cmpeq(b), ~TValue(0));
+    return retval;
+}
+
+// --------------------------------------------------------------------------
+// Function operator==()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator==(TSimdVector const & a, TSimdVector const & b)
+{
+    using TValue = typename UME::SIMD::SIMDTraits<TSimdVector>::SCALAR_T;
+    TSimdVector retval(0);
+    retval.assign(a.cmpeq(b), ~TValue(0));
+    return retval;
+}
+
+// --------------------------------------------------------------------------
+// Function operatorGt()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+cmpGt (TSimdVector const & a, TSimdVector const & b)
+{
+    using TValue = typename UME::SIMD::SIMDTraits<TSimdVector>::SCALAR_T;
+    TSimdVector retval(0);
+    retval.assign(a.cmpgt(b), ~TValue(0));
+    return retval;
+}
+
+// --------------------------------------------------------------------------
+// Function operator>()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator>(TSimdVector const & a, TSimdVector const & b)
+{
+    using TValue = typename UME::SIMD::SIMDTraits<TSimdVector>::SCALAR_T;
+    TSimdVector retval(0);
+    retval.assign(a.cmpgt(b), ~TValue(0));
+    return retval;
+}
+
+// --------------------------------------------------------------------------
+// Function max()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+max(TSimdVector const & a, TSimdVector const & b)
+{
+    return a.max(b);
+}
+
+// --------------------------------------------------------------------------
+// Function operator|()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator|(TSimdVector const & a, TSimdVector const & b)
+{
+    return a.bor(b);
+}
+
+// --------------------------------------------------------------------------
+// Function operator|=()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector &)
+operator|=(TSimdVector & a, TSimdVector const & b)
+{
+    return a.bora(b);
+}
+
+// --------------------------------------------------------------------------
+// Function operator&()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator&(TSimdVector const & a, TSimdVector const & b)
+{
+    return a.band(b);
+}
+
+// --------------------------------------------------------------------------
+// Function operator&=()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector &)
+operator&=(TSimdVector & a, TSimdVector const & b)
+{
+    return a.banda(b);
+}
+
+// --------------------------------------------------------------------------
+// Function operator~()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator~(TSimdVector const & a)
+{
+    return a.bnot();
+}
+
+// --------------------------------------------------------------------------
+// Function operator+()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator+(TSimdVector const & a, TSimdVector const & b)
+{
+    return a.add(b);
+}
+
+// --------------------------------------------------------------------------
+// Function operator-()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator-(TSimdVector const & a, TSimdVector const & b)
+{
+    return a.sub(b);
+}
+
+// --------------------------------------------------------------------------
+// Function operator*()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator*(TSimdVector const & a, TSimdVector const & b)
+{
+    return a.mul(b);
+}
+
+// --------------------------------------------------------------------------
+// Function operator/()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+operator/(TSimdVector const & a, TSimdVector const & b)
+{
+    return a.div(b);
+}
+
+// --------------------------------------------------------------------------
+// Function andNot
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+andNot(TSimdVector const & a, TSimdVector const & b)
+{
+    return a.bandnot(b);
+}
+
+
+// --------------------------------------------------------------------------
+// Function shiftRightLogical()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+shiftRightLogical(TSimdVector const & vector, const int imm)
+{
+    return vector.rsh(imm);
+}
+
+// --------------------------------------------------------------------------
+// Function blend()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TSimdVectorMask>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+blend(TSimdVector const & a, TSimdVector const & b, TSimdVectorMask const & mask)
+{
+    using TValue = typename UME::SIMD::SIMDTraits<TSimdVector>::SCALAR_T;
+    const TSimdVector truemask(~TValue(0));
+
+    return a.blend(
+        mask.cmpeq(truemask), // convert mask into umesimd's mask type
+        b
+    );
+}
+
+// --------------------------------------------------------------------------
+// Function storeu()
+// --------------------------------------------------------------------------
+
+template <typename T, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, void)
+storeu(T * memAddr, TSimdVector const & vec)
+{
+    vec.store(memAddr);
+}
+
+// --------------------------------------------------------------------------
+// Function load()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename T>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+load(T const * memAddr)
+{
+    return TSimdVector(memAddr);
+}
+
+// --------------------------------------------------------------------------
+// Function gather()
+// --------------------------------------------------------------------------
+
+template <typename TValue, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(IsSameType<TValue, typename Value<TSimdVector>::Type>, TSimdVector)
+_gather(TValue const * memAddr, TSimdVector const & idx)
+{
+    using TIndexVector = typename UME::SIMD::SIMDTraits<TSimdVector>::UINT_VEC_T;
+
+    TSimdVector a;
+    a.gather(memAddr, static_cast<TIndexVector>(idx));
+    return a;
+}
+
+template <typename TValue, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Not<IsSameType<TValue, typename Value<TSimdVector>::Type> >, TSimdVector)
+_gather(TValue const * memAddr, TSimdVector const & idx)
+{
+    using TIndexVector = typename UME::SIMD::SIMDTraits<TSimdVector>::UINT_VEC_T;
+
+    TSimdVector a;
+    for (auto i = 0u; i < TIndexVector::length(); ++i)
+    {
+        a[i] = memAddr[idx[i]];
+    }
+    return a;
+}
+
+template <typename TValue, typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+gather(TValue const * memAddr, TSimdVector const & idx)
+{
+    return _gather(memAddr, idx);
+}
+
+// --------------------------------------------------------------------------
+// Function shuffleVector()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector1, typename TSimdVector2>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector1> >, TSimdVector1)
+shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices)
+{
+    return vector.swizzle(indices);
+}
+
+}
+
+#endif // SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_UMESIMD_IMPL_H_
diff --git a/include/seqan/stream/iostream_bgzf.h b/include/seqan/stream/iostream_bgzf.h
index 4a7347e..4cf3a0e 100644
--- a/include/seqan/stream/iostream_bgzf.h
+++ b/include/seqan/stream/iostream_bgzf.h
@@ -20,6 +20,10 @@
 #ifndef INCLUDE_SEQAN_STREAM_IOSTREAM_BGZF_H_
 #define INCLUDE_SEQAN_STREAM_IOSTREAM_BGZF_H_
 
+#ifndef SEQAN_BGZF_NUM_THREADS
+#define SEQAN_BGZF_NUM_THREADS 16
+#endif
+
 namespace seqan {
 
 const unsigned BGZF_MAX_BLOCK_SIZE = 64 * 1024;
@@ -146,7 +150,7 @@ public:
     std::vector<TFuture>         threads;
 
     basic_bgzf_streambuf(ostream_reference ostream_,
-                         size_t numThreads = 16,
+                         size_t numThreads = SEQAN_BGZF_NUM_THREADS,
                          size_t jobsPerThread = 8) :
         numThreads(numThreads),
         numJobs(numThreads * jobsPerThread),
@@ -494,7 +498,7 @@ public:
     TBuffer              putbackBuffer;
 
     basic_unbgzf_streambuf(istream_reference istream_,
-                           size_t numThreads = 16,
+                           size_t numThreads = SEQAN_BGZF_NUM_THREADS,
                            size_t jobsPerThread = 8) :
         serializer(istream_),
         numThreads(numThreads),
diff --git a/include/seqan/stream/tokenization.h b/include/seqan/stream/tokenization.h
index fa9a1bb..9595cb4 100644
--- a/include/seqan/stream/tokenization.h
+++ b/include/seqan/stream/tokenization.h
@@ -397,11 +397,30 @@ inline void readOne(TTarget & target, TFwdIterator &iter)
 
 //TODO(singer) to be revised
 template <typename TValue, typename TFwdIterator>
-inline void readRawPod(TValue & value, TFwdIterator &srcIter)
+inline void readRawPodImpl(TValue & value, TFwdIterator &srcIter)
 {
     write((char*)&value, srcIter, sizeof(TValue));
 }
 
+template <typename TValue, typename TFwdIterator>
+inline std::enable_if_t<std::is_arithmetic<TValue>::value>
+readRawPod(TValue & value, TFwdIterator &srcIter)
+{
+    readRawPodImpl(value, srcIter);
+    ensure_little_endian(value);
+}
+
+template <typename TValue, typename TFwdIterator>
+inline std::enable_if_t<!std::is_arithmetic<TValue>::value>
+readRawPod(TValue & value, TFwdIterator &srcIter)
+{
+#if SEQAN_BIG_ENDIAN
+    #error "You are deserialising a data structure on big endian architecture that needs a custom reader. THIS IS A BUG!"
+#else
+    readRawPodImpl(value, srcIter);
+#endif
+}
+
 // ----------------------------------------------------------------------------
 // Function readLine()
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/version.h b/include/seqan/version.h
index 7716422..ac318b7 100644
--- a/include/seqan/version.h
+++ b/include/seqan/version.h
@@ -39,9 +39,9 @@
 
 #define SEQAN_VERSION_MAJOR 2
 
-#define SEQAN_VERSION_MINOR 3
+#define SEQAN_VERSION_MINOR 4
 
-#define SEQAN_VERSION_PATCH 2
+#define SEQAN_VERSION_PATCH 0
 
 #define SEQAN_VERSION_PRE_RELEASE 0
 
diff --git a/manual/source/Infrastructure/Use/CustomBuildSystem.rst b/manual/source/Infrastructure/Use/CustomBuildSystem.rst
index b6d1423..1ed31a0 100644
--- a/manual/source/Infrastructure/Use/CustomBuildSystem.rst
+++ b/manual/source/Infrastructure/Use/CustomBuildSystem.rst
@@ -211,6 +211,21 @@ meaning
 usage
  add compiler flag: ``-DSEQAN_DISABLE_VERSION_CHECK`` 
 
+SEQAN_BGZF_NUM_THREADS
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+possible value
+ positive integer
+
+default
+ 16
+
+meaning
+ Number of threads to use for BGZF I/O.
+
+usage
+ add compiler flag: ``-DSEQAN_BGZF_NUM_THREADS=value`` 
+
 Settings Projects Using Seqan
 -----------------------------
 
diff --git a/manual/source/Tutorial/DataStructures/Sequence/StringsAndSegments.rst b/manual/source/Tutorial/DataStructures/Sequence/StringsAndSegments.rst
index c960684..b521657 100644
--- a/manual/source/Tutorial/DataStructures/Sequence/StringsAndSegments.rst
+++ b/manual/source/Tutorial/DataStructures/Sequence/StringsAndSegments.rst
@@ -112,7 +112,7 @@ To empty a :dox:`String`, the function :dox:`StringConcept#clear` resets the obj
 .. includefrags:: demos/tutorial/sequences/example_functionality2.cpp
     :fragment: clear
 
-SeqAn offers a range of other functions for the work with the :dox:`String` class, e.g. :dox:`AssignableConcept#assign`, :dox:`RandomAccessContainerConcept#assignValue`, :dox:`RandomAccessContainerConcept#value`, :dox:`IteratorAssociatedTypesConcept#getValue`, :dox:`ContainerConcept#empty`, etc.
+SeqAn offers a range of other functions for the work with the :dox:`String` class, e.g. :dox:`AssignableConcept#assign`, :dox:`RandomAccessContainerConcept#assignValue`, :dox:`ContainerConcept#empty`, etc.
 The full list of functions you can find in the documentation :dox:`String`.
 
 Assignment 1
diff --git a/manual/source/Tutorial/GettingStarted/AFirstExample.rst b/manual/source/Tutorial/GettingStarted/AFirstExample.rst
index ff7446f..aad59cf 100644
--- a/manual/source/Tutorial/GettingStarted/AFirstExample.rst
+++ b/manual/source/Tutorial/GettingStarted/AFirstExample.rst
@@ -108,6 +108,10 @@ Assignment 1
 
         .. includefrags:: demos/tutorial/a_first_example/solution_1.cpp
 
+        Your output should look like this:
+
+        .. includefrags:: demos/tutorial/a_first_example/solution_1.cpp.stdout
+
 SeqAn and Templates
 -------------------
 
@@ -223,6 +227,11 @@ Assignment 2
      .. container:: foldable
 
         .. includefrags:: demos/tutorial/a_first_example/solution_2.cpp
+           :fragment: all
+
+        Your output should look like this:
+
+        .. includefrags:: demos/tutorial/a_first_example/solution_2.cpp.stdout
 
 The Role of References in SeqAn
 -------------------------------
@@ -273,11 +282,15 @@ Assignment 3
         .. includefrags:: demos/tutorial/a_first_example/solution_3.cpp
            :fragment: head_local
 
-
    Solution
      .. container:: foldable
 
         .. includefrags:: demos/tutorial/a_first_example/solution_3.cpp
+           :fragment: all
+
+        Your output should look like this:
+
+        .. includefrags:: demos/tutorial/a_first_example/solution_3.cpp.stdout
 
 Generic and Reusable Code
 -------------------------
@@ -336,6 +349,12 @@ Assignment 4
 
         .. includefrags:: demos/tutorial/a_first_example/solution_4.cpp
 
+        Your output should look like this:
+
+        .. includefrags:: demos/tutorial/a_first_example/solution_4.cpp.stdout
+
+.. _oop-to-seqan:
+
 From Object-Oriented Programming to SeqAn
 -----------------------------------------
 
@@ -388,6 +407,10 @@ Assignment 5
 
         .. includefrags:: demos/tutorial/a_first_example/solution_5.cpp
 
+        Your output should look like this:
+
+        .. includefrags:: demos/tutorial/a_first_example/solution_5.cpp.stdout
+
 Tags in SeqAn
 -------------
 
@@ -453,6 +476,10 @@ Assignment 6
 
         .. includefrags:: demos/tutorial/a_first_example/solution_6.cpp
 
+        Your output should look like this:
+
+        .. includefrags:: demos/tutorial/a_first_example/solution_6.cpp.stdout
+
 Obviously this is only a toy example in which we could have named the two ``print()`` functions differently.
 However, often this is not the case when the programs become more complex.
 Because SeqAn is very generic we do not know the datatypes of template functions in advance.
@@ -470,5 +497,7 @@ There are several tutorials which will teach you how to use the different SeqAn
 Below you find the complete code for our example with the corresponding output.
 
 .. includefrags:: demos/tutorial/a_first_example/final_result.cpp
-   :fragment: result
 
+Your output should look like this:
+
+.. includefrags:: demos/tutorial/a_first_example/final_result.cpp.stdout
diff --git a/manual/source/Tutorial/GettingStarted/BackgroundAndMotivation.rst b/manual/source/Tutorial/GettingStarted/BackgroundAndMotivation.rst
index 68d4c63..13e3ea4 100644
--- a/manual/source/Tutorial/GettingStarted/BackgroundAndMotivation.rst
+++ b/manual/source/Tutorial/GettingStarted/BackgroundAndMotivation.rst
@@ -139,7 +139,7 @@ In SeqAn, we use a technique called `template subclassing <tutorial-getting-star
 This technique provides `polymorphism <http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming>`_ into C++ programs at **compile time** using templates.
 Such static polymorphism is different from **runtime polymorphism** which is supported in C++ using subclassing and virtual functions.
 It comes at the cost of some additional typing but has the advantage that the compiler can inline all function calls and thus achieve better performance.
-An example will be given in `the section "From OOP to SeqAn" in the First Steps Tutorial <tutorial-getting-started-first-steps-in-seqan>`_.
+An example will be given in :ref:`the section "From OOP to SeqAn" in the First Steps Tutorial <oop-to-seqan>`.
 
 .. todo::
     We need a little code example here.
diff --git a/manual/source/seqan.bib b/manual/source/seqan.bib
index d3b6e79..fe09f03 100644
--- a/manual/source/seqan.bib
+++ b/manual/source/seqan.bib
@@ -125,17 +125,6 @@
   publisher={Wiley Online Library}
 }
 
- at article{Langmead2009,
-  doi={10.1186/gb-2009-10-3-r25},
-  title={Ultrafast and memory-efficient alignment of short DNA sequences to the human genome},
-  author={Langmead, Ben and Trapnell, Cole and Pop, Mihai and Salzberg, Steven L and others},
-  journal={Genome Biol},
-  volume={10},
-  number={3},
-  pages={R25},
-  year={2009}
-}
-
 @article{Mortazavi2008,
   doi={10.1038/nmeth.1226},
   title={Mapping and quantifying mammalian transcriptomes by RNA-Seq},
diff --git a/tests/align/CMakeLists.txt b/tests/align/CMakeLists.txt
index c028716..214d76c 100644
--- a/tests/align/CMakeLists.txt
+++ b/tests/align/CMakeLists.txt
@@ -83,5 +83,6 @@ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SEQAN_CXX_FLAGS}")
 
 add_test (NAME test_test_align COMMAND $<TARGET_FILE:test_align>)
 if (ALIGN_SIMD_TEST)
-    add_test (NAME test_test_align_simd COMMAND $<TARGET_FILE:test_align_simd>)
+    include (SeqAnSimdUtility)
+    add_simd_platform_tests(test_align_simd)
 endif ()
diff --git a/tests/bam_io/test_bam_index.h b/tests/bam_io/test_bam_index.h
index a1192df..48aabda 100644
--- a/tests/bam_io/test_bam_index.h
+++ b/tests/bam_io/test_bam_index.h
@@ -95,6 +95,8 @@ SEQAN_DEFINE_TEST(test_bam_io_bam_index_open)
     SEQAN_ASSERT(found);
     SEQAN_ASSERT_NOT(jumpToRegion(bamFile, found, 1, 1, 10, baiIndex));
     SEQAN_ASSERT_NOT(found);
+    SEQAN_ASSERT(jumpToRegion(bamFile, found, 0, 20, 100, baiIndex));
+    SEQAN_ASSERT_NOT(found);
 }
 
 SEQAN_DEFINE_TEST(test_bam_io_bam_index_save)
diff --git a/tests/basic/CMakeLists.txt b/tests/basic/CMakeLists.txt
index bb15a93..e9a23b7 100644
--- a/tests/basic/CMakeLists.txt
+++ b/tests/basic/CMakeLists.txt
@@ -123,12 +123,6 @@ add_executable (
   test_basic_iterator.h)
 target_link_libraries (test_basic_iterator ${SEQAN_LIBRARIES})
 
-add_executable (
-  test_basic_simd_vector
-  test_basic_simd_vector.cpp
-  test_basic_simd_vector.h)
-target_link_libraries (test_basic_simd_vector ${SEQAN_LIBRARIES})
-
 # Add CXX flags found by find_package (SeqAn).
 set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SEQAN_CXX_FLAGS}")
 
@@ -149,4 +143,3 @@ add_test (NAME test_test_basic_smart_pointer COMMAND $<TARGET_FILE:test_basic_sm
 add_test (NAME test_test_basic_container COMMAND $<TARGET_FILE:test_basic_container>)
 add_test (NAME test_test_basic_proxy COMMAND $<TARGET_FILE:test_basic_proxy>)
 add_test (NAME test_test_basic_iterator COMMAND $<TARGET_FILE:test_basic_iterator>)
-add_test (NAME test_test_basic_simd_vector COMMAND $<TARGET_FILE:test_basic_simd_vector>)
diff --git a/tests/basic/test_basic_simd_vector.h b/tests/basic/test_basic_simd_vector.h
deleted file mode 100644
index e6b1519..0000000
--- a/tests/basic/test_basic_simd_vector.h
+++ /dev/null
@@ -1,155 +0,0 @@
-// ==========================================================================
-//                 SeqAn - The Library for Sequence Analysis
-// ==========================================================================
-// Copyright (c) 2006-2015, Knut Reinert, FU Berlin
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above copyright
-//       notice, this list of conditions and the following disclaimer in the
-//       documentation and/or other materials provided with the distribution.
-//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
-//       its contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-// DAMAGE.
-//
-// ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tests for SIMD vectors.
-// ==========================================================================
-
-#ifndef SEQAN_CORE_TESTS_BASIC_TEST_BASIC_SIMD_VECTOR_H_
-#define SEQAN_CORE_TESTS_BASIC_TEST_BASIC_SIMD_VECTOR_H_
-
-#include <random>
-
-#include <seqan/sequence.h>
-#include <seqan/misc/bit_twiddling.h>
-#include <seqan/basic/basic_simd_vector.h>
-
-#if defined(SEQAN_SIMD_ENABLED)
-namespace seqan {
-
-template <int ROWS, typename TVector>
-inline void test_matrix_transpose()
-{
-    typedef typename Value<TVector>::Type TValue;
-    typedef TVector TMatrix[LENGTH<TVector>::VALUE];
-    const int COLS = LENGTH<TVector>::VALUE;
-    
-    String<TValue> random;
-    resize(random, ROWS * COLS);
-
-    std::mt19937 rng;
-    std::uniform_int_distribution<TValue> pdf(0, MaxValue<TValue>::VALUE);
-    for (unsigned i = 0; i < length(random); ++i)
-        random[i] = pdf(rng);
-
-    TMatrix tmp;
-    for (int i = 0; i < ROWS; ++i)
-        for (int j = 0; j < COLS; ++j)
-            tmp[i][j] = random[i * COLS + j];
-
-//    for(int i=0;i<ROWS;++i)
-//        print(std::cout, tmp[i]) << std::endl;
-
-    transpose<ROWS>(tmp);
-
-//    std::cout << std::endl;
-//    std::cout << std::endl;
-//    for(int i=0;i<DIM;++i)
-//        print(std::cout, tmp[i]) << std::endl;
-    
-    for (int i = 0; i < ROWS; ++i)
-        for (int j = 0; j < COLS; ++j)
-            SEQAN_ASSERT_EQ(tmp[i][j], random[j * ROWS + i]);
-}
-
-}
-
-#ifdef SEQAN_SSE4
-
-SEQAN_DEFINE_TEST(test_basic_simd_shuffle)
-{
-    seqan::SimdVector<unsigned short, 8>::Type vec;
-    seqan::SimdVector<unsigned char, 8>::Type  indices;
-
-    for (int i = 0; i < 8; ++i)
-        vec[i] = i * 259 + 3;
-
-    for (int i = 0; i < 8; ++i)
-        indices[i] = 7 - i;
-
-    vec = seqan::shuffleVector(vec, indices);
-
-    for (int i = 0; i < 8; ++i)
-        SEQAN_ASSERT_EQ(vec[i], (7 - i) * 259 + 3);
-}
-
-SEQAN_DEFINE_TEST(test_basic_simd_transpose_8x8)
-{
-    seqan::test_matrix_transpose<8, seqan::SimdVector<unsigned char, 8>::Type>();
-}
-
-SEQAN_DEFINE_TEST(test_basic_simd_transpose_16x16)
-{
-    seqan::test_matrix_transpose<16, seqan::SimdVector<unsigned char, 16>::Type>();
-}
-
-#ifdef __AVX2__
-
-SEQAN_DEFINE_TEST(test_basic_simd_shuffle_avx)
-{
-    seqan::SimdVector<unsigned short, 16>::Type vec;
-    seqan::SimdVector<unsigned char, 16>::Type  indices;
-    
-    const int perm[] = {1,4,2,6,3,5,0,7};
-
-    for (int i = 0; i < 8; ++i)
-    {
-        vec[i]   = i * 259 + 3;
-        vec[i+8] = i * 432 + 9;
-    }
-
-    for (int i = 0; i < 8; ++i)
-    {
-        indices[i]   = 7 - i;
-        indices[i+8] = perm[i];
-    }
-
-    vec = seqan::shuffleVector(vec, indices);
-
-    for (int i = 0; i < 8; ++i)
-    {
-        SEQAN_ASSERT_EQ(vec[i],   (7 - i) * 259 + 3);
-        SEQAN_ASSERT_EQ(vec[i+8], perm[i] * 432 + 9);
-    }
-}
-
-
-SEQAN_DEFINE_TEST(test_basic_simd_transpose_32x32)
-{
-    seqan::test_matrix_transpose<32, seqan::SimdVector<unsigned char, 32>::Type >();
-}
-
-#endif  // #ifdef __AVX2__
-#endif  // #ifdef SEQAN_SSE4
-#endif  // SEQAN_SIMD_ENABLED
-
-#endif  // #ifndef SEQAN_CORE_TESTS_BASIC_TEST_BASIC_SIMD_VECTOR_H_
diff --git a/tests/blast/test_blast_output.h b/tests/blast/test_blast_output.h
index 79c85d0..e470835 100644
--- a/tests/blast/test_blast_output.h
+++ b/tests/blast/test_blast_output.h
@@ -179,7 +179,7 @@ _testBlastOutputGenerateContent(TFile & file,
 
             computeAlignmentStats(m, context);
             computeBitScore(m, context);
-            computeEValue(m, context);
+            computeEValue(m, records[q].qLength, context);
         }
     }
 
diff --git a/tests/index/test_index_stree_iterators.cpp b/tests/index/test_index_stree_iterators.cpp
index 1c1df97..d901a60 100644
--- a/tests/index/test_index_stree_iterators.cpp
+++ b/tests/index/test_index_stree_iterators.cpp
@@ -57,6 +57,7 @@ SEQAN_BEGIN_TESTSUITE(test_index)
 	SEQAN_CALL_TEST(testEmptyIndex);
 	SEQAN_CALL_TEST(testIssue509);
 	SEQAN_CALL_TEST(testIssue509b);
+	SEQAN_CALL_TEST(goDownOnEmptyString);
 	SEQAN_CALL_TEST(testSTreeIterators_Wotd);
 	SEQAN_CALL_TEST(testSTreeIterators_WotdOriginal);
 	SEQAN_CALL_TEST(testSTreeIterators_Esa);
diff --git a/tests/index/test_stree_iterators.h b/tests/index/test_stree_iterators.h
index 40468a8..4c2f51e 100644
--- a/tests/index/test_stree_iterators.h
+++ b/tests/index/test_stree_iterators.h
@@ -103,6 +103,24 @@ SEQAN_DEFINE_TEST(testIssue509b)
     SEQAN_ASSERT(goDown(iterator, seq));
 }
 
+SEQAN_DEFINE_TEST(goDownOnEmptyString)
+{
+    typedef Index<DnaString, FMIndex<> > TIndex;
+    typedef Iter<TIndex, VSTree<TopDown<> > > TIter;
+
+    DnaString text("GCCTC");
+    TIndex index(text);
+    TIter it(index);
+
+    goDown(it, "C");
+    goDown(it);
+    goDown(it, "");
+    goRight(it);
+    SEQAN_ASSERT_EQ(representative(it), DnaString("GC"));
+    goRight(it);
+    SEQAN_ASSERT_EQ(representative(it), DnaString("TC"));
+}
+
 SEQAN_DEFINE_TEST(testBuild)
 {
         typedef String<char> TText;
diff --git a/tests/journaled_string_tree/test_journaled_string_tree_traverser.cpp b/tests/journaled_string_tree/test_journaled_string_tree_traverser.cpp
index 5534716..f23e2ed 100644
--- a/tests/journaled_string_tree/test_journaled_string_tree_traverser.cpp
+++ b/tests/journaled_string_tree/test_journaled_string_tree_traverser.cpp
@@ -48,6 +48,7 @@ SEQAN_BEGIN_TESTSUITE(test_journaled_string_tree_traverser)
     SEQAN_CALL_TEST(test_journaled_string_tree_traverser_context_size);
     SEQAN_CALL_TEST(test_journaled_string_tree_traverser_branch_size);
     SEQAN_CALL_TEST(test_journaled_string_tree_traverser_at_end);
+    SEQAN_CALL_TEST(test_journaled_string_tree_traverser_is_base);
     SEQAN_CALL_TEST(test_journaled_string_tree_traverser_advance);
     SEQAN_CALL_TEST(test_journaled_string_tree_traverser_context_iterator);
 
diff --git a/tests/journaled_string_tree/test_journaled_string_tree_traverser.h b/tests/journaled_string_tree/test_journaled_string_tree_traverser.h
index 8b2feee..48151ba 100644
--- a/tests/journaled_string_tree/test_journaled_string_tree_traverser.h
+++ b/tests/journaled_string_tree/test_journaled_string_tree_traverser.h
@@ -290,6 +290,22 @@ SEQAN_DEFINE_TEST(test_journaled_string_tree_traverser_at_end)
     SEQAN_ASSERT_EQ(atEnd(test), true);
 }
 
+SEQAN_DEFINE_TEST(test_journaled_string_tree_traverser_is_base)
+{
+    typedef JournaledStringTree<DnaString> TJst;
+    typedef TraverserImpl<TJst, JstTraversalSpec<> > TTraverser;
+
+    TJst jst = JstMockGenerator::_createSimpleJst<TJst>();
+    TTraverser test(jst, 1);
+
+    SEQAN_ASSERT(!isBase(test));
+    for (unsigned i = 0; i < 31; ++i)
+    {
+        advance(test, 1);
+    }
+    SEQAN_ASSERT(isBase(test));
+}
+
 SEQAN_DEFINE_TEST(test_journaled_string_tree_traverser_context_size)
 {
     typedef JournaledStringTree<DnaString> TJst;
diff --git a/tests/reduced_aminoacid/test_reduced_aminoacid.cpp b/tests/reduced_aminoacid/test_reduced_aminoacid.cpp
index 66bb7c6..b0e55a3 100644
--- a/tests/reduced_aminoacid/test_reduced_aminoacid.cpp
+++ b/tests/reduced_aminoacid/test_reduced_aminoacid.cpp
@@ -42,6 +42,11 @@
 SEQAN_BEGIN_TESTSUITE(test_reduced_aminoacid)
 {
 //     SEQAN_CALL_TEST(test_reduced_aminoacid_cluster_red);
+    SEQAN_CALL_TEST(test_reduced_aminoacid_buchfink11);
+    SEQAN_CALL_TEST(test_reduced_aminoacid_cannata10);
+    SEQAN_CALL_TEST(test_reduced_aminoacid_li10);
+    SEQAN_CALL_TEST(test_reduced_aminoacid_solis10);
+    SEQAN_CALL_TEST(test_reduced_aminoacid_murphy5);
     SEQAN_CALL_TEST(test_reduced_aminoacid_murphy10);
     SEQAN_CALL_TEST(test_reduced_aminoacid_murphy10_moditerators);
     SEQAN_CALL_TEST(test_reduced_aminoacid_murphy10_modview_fmindex);
diff --git a/tests/reduced_aminoacid/test_reduced_aminoacid.h b/tests/reduced_aminoacid/test_reduced_aminoacid.h
index 97158e0..7e017d9 100644
--- a/tests/reduced_aminoacid/test_reduced_aminoacid.h
+++ b/tests/reduced_aminoacid/test_reduced_aminoacid.h
@@ -92,6 +92,101 @@ SEQAN_DEFINE_TEST(test_reduced_aminoacid_cluster_red)
 }
 #endif
 
+SEQAN_DEFINE_TEST(test_reduced_aminoacid_buchfink11)
+{
+    typedef SimpleType<unsigned char, ReducedAminoAcid_<Buchfink11> >
+            ReducedAminoAcidBuchfink11;
+
+    CharString str = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz*+#";
+    String<AminoAcid> aas = "ABCDEFGHIJKLMNOPQRSTUVWYZX*";
+
+    // N = 11
+    {
+        String<ReducedAminoAcidBuchfink11> conv = str;
+        SEQAN_ASSERT_EQ(
+            CharString(conv),
+            "AABBCCBBBBFFGGHHIIIIBBIIMMBBBBPPBBBBAAAACCIIWWAAYYBBFAA");
+        conv = aas;
+        SEQAN_ASSERT_EQ(CharString(conv), "ABCBBFGHIIBIMBBPBBAACIWYBAF");
+    }
+}
+
+SEQAN_DEFINE_TEST(test_reduced_aminoacid_cannata10)
+{
+    typedef SimpleType<unsigned char, ReducedAminoAcid_<Cannata10> >
+            ReducedAminoAcidCannata10;
+
+    CharString str = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz*+#";
+    String<AminoAcid> aas = "ABCDEFGHIJKLMNOPQRSTUVWYZX*";
+
+    // N = 10
+    {
+        String<ReducedAminoAcidCannata10> conv = str;
+        SEQAN_ASSERT_EQ(
+            CharString(conv),
+            "AABBCCBBEEFFAAHHIIIIKKIIIIBBKKPPEEKKAAAACCIIWWAAFFEEFAA");
+        conv = aas;
+        SEQAN_ASSERT_EQ(CharString(conv), "ABCBEFAHIIKIIBKPEKAACIWFEAF");
+    }
+}
+
+SEQAN_DEFINE_TEST(test_reduced_aminoacid_li10)
+{
+    typedef SimpleType<unsigned char, ReducedAminoAcid_<Li10> >
+            ReducedAminoAcidLi10;
+
+    CharString str = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz*+#";
+    String<AminoAcid> aas = "ABCDEFGHIJKLMNOPQRSTUVWYZX*";
+
+    // N = 10
+    {
+        String<ReducedAminoAcidLi10> conv = str;
+        SEQAN_ASSERT_EQ(
+            CharString(conv),
+            "AABBCCBBBBFFGGHHIIJJKKJJJJHHKKPPBBKKAAAACCIIFFAAFFBBFAA");
+        conv = aas;
+        SEQAN_ASSERT_EQ(CharString(conv), "ABCBBFGHIJKJJHKPBKAACIFFBAF");
+    }
+}
+
+SEQAN_DEFINE_TEST(test_reduced_aminoacid_solis10)
+{
+    typedef SimpleType<unsigned char, ReducedAminoAcid_<Solis10> >
+            ReducedAminoAcidSolis10;
+
+    CharString str = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz*+#";
+    String<AminoAcid> aas = "ABCDEFGHIJKLMNOPQRSTUVWYZX*";
+
+    // N = 10
+    {
+        String<ReducedAminoAcidSolis10> conv = str;
+        SEQAN_ASSERT_EQ(
+            CharString(conv),
+            "AABBCCBBBBFFGGHHIIIIKKIIIIGGHHPPGGHHGGPPCCIIWWAAWWBBFAA");
+        conv = aas;
+        SEQAN_ASSERT_EQ(CharString(conv), "ABCBBFGHIIKIIGHPGHGPCIWWBAF");
+    }
+}
+
+SEQAN_DEFINE_TEST(test_reduced_aminoacid_murphy5)
+{
+    typedef SimpleType<unsigned char, ReducedAminoAcid_<Murphy5> >
+            ReducedAminoAcidMurphy5;
+
+    CharString str = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz*+#";
+    String<AminoAcid> aas = "ABCDEFGHIJKLMNOPQRSTUVWYZX*";
+
+    // N = 5
+    {
+        String<ReducedAminoAcidMurphy5> conv = str;
+        SEQAN_ASSERT_EQ(
+            CharString(conv),
+            "AABBCCBBBBFFAAHHCCCCHHCCCCBBHHAABBHHAAAACCCCFFAAFFBBFAA");
+        conv = aas;
+        SEQAN_ASSERT_EQ(CharString(conv), "ABCBBFAHCCHCCBHABHAACCFFBAF");
+    }
+}
+
 SEQAN_DEFINE_TEST(test_reduced_aminoacid_murphy10)
 {
     typedef SimpleType<unsigned char, ReducedAminoAcid_<Murphy10> >
diff --git a/tests/simd/CMakeLists.txt b/tests/simd/CMakeLists.txt
new file mode 100644
index 0000000..02e17c9
--- /dev/null
+++ b/tests/simd/CMakeLists.txt
@@ -0,0 +1,48 @@
+# ===========================================================================
+#                  SeqAn - The Library for Sequence Analysis
+# ===========================================================================
+# File: /tests/basic/CMakeLists.txt
+#
+# CMakeLists.txt file for the basic module tests.
+# ===========================================================================
+
+cmake_minimum_required (VERSION 3.0.0)
+project (seqan_tests_simd CXX)
+message (STATUS "Configuring tests/simd")
+
+# ----------------------------------------------------------------------------
+# Dependencies
+# ----------------------------------------------------------------------------
+
+# Search SeqAn and select dependencies.
+find_package (SeqAn REQUIRED)
+include (SeqAnSimdUtility)
+
+# ----------------------------------------------------------------------------
+# Build Setup
+# ----------------------------------------------------------------------------
+
+# Add include directories.
+include_directories (${SEQAN_INCLUDE_DIRS})
+
+# Add definitions set by find_package (SeqAn).
+add_definitions (${SEQAN_DEFINITIONS})
+
+# Update the list of file names below if you add source files to your test.
+add_executable (
+  test_simd_vector
+  test_simd_vector.cpp
+  test_simd_vector.h)
+target_link_libraries (test_simd_vector ${SEQAN_LIBRARIES})
+if (COMPILER_CLANG)
+  target_compile_options(test_simd_vector PRIVATE -ftemplate-depth=1024)
+endif()
+
+# Add CXX flags found by find_package (SeqAn).
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SEQAN_CXX_FLAGS}")
+
+# ----------------------------------------------------------------------------
+# Register with CTest
+# ----------------------------------------------------------------------------
+
+add_simd_platform_tests(test_simd_vector)
diff --git a/tests/basic/test_basic_simd_vector.cpp b/tests/simd/test_simd_vector.cpp
similarity index 78%
rename from tests/basic/test_basic_simd_vector.cpp
rename to tests/simd/test_simd_vector.cpp
index 94b6979..b9de950 100644
--- a/tests/basic/test_basic_simd_vector.cpp
+++ b/tests/simd/test_simd_vector.cpp
@@ -30,26 +30,26 @@
 //
 // ==========================================================================
 // Author: David Weese <david.weese at fu-berlin.de>
+//         Marcel Ehrhardt <marcel.ehrhardt at fu-berlin.de>
 // ==========================================================================
 // Tests for SIMD vectors.
 // ==========================================================================
 
 #include <seqan/basic.h>
-#include "test_basic_simd_vector.h"
+#include "test_simd_vector.h"
 
-SEQAN_BEGIN_TESTSUITE(test_basic_simd_vector)
+SEQAN_BEGIN_TESTSUITE(test_simd_vector)
 {
-#ifdef SEQAN_SIMD_ENABLED
-#ifdef SEQAN_SSE4
-    SEQAN_CALL_TEST(test_basic_simd_shuffle);
-    SEQAN_CALL_TEST(test_basic_simd_transpose_8x8);
-    SEQAN_CALL_TEST(test_basic_simd_transpose_16x16);
-#ifdef __AVX2__
-    SEQAN_CALL_TEST(test_basic_simd_shuffle_avx);
-    SEQAN_CALL_TEST(test_basic_simd_transpose_32x32);
-#endif  // #ifdef __AVX2__
-#endif  // #ifdef SEQAN_SSE4
-#endif
+#if defined(SEQAN_SEQANSIMD_ENABLED) && defined(__SSE4_1__)
+    SEQAN_CALL_TEST(test_simd_transpose_8x8);
+    SEQAN_CALL_TEST(test_simd_transpose_16x16);
+    SEQAN_CALL_TEST(test_simd_types);
+#endif  // defined(SEQAN_SEQANSIMD_ENABLED) && defined(__SSE4_1__)
+
+#if defined(SEQAN_SEQANSIMD_ENABLED) && defined(__AVX2__)
+    SEQAN_CALL_TEST(test_simd_transpose_32x32);
+#endif  // defined(SEQAN_SEQANSIMD_ENABLED) && defined(__AVX2__)
+
+    return seqan::TestSystem::runAll();
 }
 SEQAN_END_TESTSUITE
-
diff --git a/tests/simd/test_simd_vector.h b/tests/simd/test_simd_vector.h
new file mode 100644
index 0000000..d9e3c24
--- /dev/null
+++ b/tests/simd/test_simd_vector.h
@@ -0,0 +1,953 @@
+// ==========================================================================
+//                 SeqAn - The Library for Sequence Analysis
+// ==========================================================================
+// Copyright (c) 2006-2015, Knut Reinert, FU Berlin
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+//       its contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+// DAMAGE.
+//
+// ==========================================================================
+// Author: David Weese <david.weese at fu-berlin.de>
+//         Marcel Ehrhardt <marcel.ehrhardt at fu-berlin.de>
+// ==========================================================================
+// Tests for SIMD vectors.
+// ==========================================================================
+
+#ifndef SEQAN_CORE_TESTS_SIMD_TEST_SIMD_VECTOR_H_
+#define SEQAN_CORE_TESTS_SIMD_TEST_SIMD_VECTOR_H_
+
+#include <seqan/simd.h>
+#include <random>
+#include <seqan/sequence.h>
+#include <seqan/misc/bit_twiddling.h>
+
+#if defined(SEQAN_SIMD_ENABLED)
+namespace seqan {
+
+template <int ROWS, typename TVector>
+inline void test_matrix_transpose()
+{
+    typedef typename Value<TVector>::Type TValue;
+    typedef TVector TMatrix[LENGTH<TVector>::VALUE];
+    const int COLS = LENGTH<TVector>::VALUE;
+
+    String<TValue> random;
+    resize(random, ROWS * COLS);
+
+    std::mt19937 rng;
+    // http://stackoverflow.com/questions/31460733/why-arent-stduniform-int-distributionuint8-t-and-stduniform-int-distri
+    std::uniform_int_distribution<uint64_t> pdf(0, MaxValue<TValue>::VALUE);
+    for (unsigned i = 0; i < length(random); ++i)
+        random[i] = static_cast<TValue>(pdf(rng));
+
+    TMatrix tmp;
+    for (int i = 0; i < ROWS; ++i)
+        for (int j = 0; j < COLS; ++j)
+            tmp[i][j] = random[i * COLS + j];
+
+//    for(int i=0;i<ROWS;++i)
+//        print(std::cout, tmp[i]) << std::endl;
+
+    transpose<ROWS>(tmp);
+
+//    std::cout << std::endl;
+//    std::cout << std::endl;
+//    for(int i=0;i<DIM;++i)
+//        print(std::cout, tmp[i]) << std::endl;
+
+    for (int i = 0; i < ROWS; ++i)
+        for (int j = 0; j < COLS; ++j)
+            SEQAN_ASSERT_EQ(tmp[i][j], random[j * ROWS + i]);
+}
+
+template <typename TSimdVector>
+void fillVectors(TSimdVector & a, TSimdVector & b)
+{
+    using namespace seqan;
+    constexpr auto length = LENGTH<TSimdVector>::VALUE;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        a[i] = (i - 1) * 3;
+        b[i] = length - i;
+    }
+}
+
+template <typename TSimdVector, typename TSize>
+void reverseIndexSequence(TSimdVector & idx, TSize length)
+{
+    for (auto i = 0; i < length; ++i)
+    {
+        // note: umesimd swizzle interface has no a[i] = i; support.
+        assignValue(idx, i, length - i - 1);
+    }
+}
+
+template <typename TSimdVector>
+constexpr auto trueValue()
+{
+    using TValue = typename Value<TSimdVector>::Type;
+    return static_cast<TValue>(-1);
+}
+
+} // namespace seqan
+
+// ----------------------------------------------------------------------------
+// Configuration of typed tests for simd vectors.
+// ----------------------------------------------------------------------------
+
+template <typename TSimdVector_>
+class SimdVectorTestCommon : public seqan::Test
+{
+public:
+    using TValue = typename seqan::Value<TSimdVector_>::Type;
+    constexpr static auto const LENGTH = seqan::LENGTH<TSimdVector_>::VALUE;
+    using TSimdVector = TSimdVector_;
+};
+
+template <typename TSimdVector_>
+class SimdVectorTestGather : public seqan::Test
+{
+public:
+    using TValue = typename seqan::Value<TSimdVector_>::Type;
+    constexpr static auto const LENGTH = seqan::LENGTH<TSimdVector_>::VALUE;
+    using TSimdVector = TSimdVector_;
+};
+
+typedef
+        seqan::TagList<seqan::SimdVector<int8_t, 16>::Type,
+        seqan::TagList<seqan::SimdVector<int16_t, 8>::Type,
+        seqan::TagList<seqan::SimdVector<int32_t, 4>::Type,
+        seqan::TagList<seqan::SimdVector<int64_t, 2>::Type,
+        seqan::TagList<seqan::SimdVector<uint8_t, 16>::Type,
+        seqan::TagList<seqan::SimdVector<uint16_t, 8>::Type,
+        seqan::TagList<seqan::SimdVector<uint32_t, 4>::Type,
+        seqan::TagList<seqan::SimdVector<uint64_t, 2>::Type
+        #if SEQAN_SIZEOF_MAX_VECTOR >= 32
+        , // Extension of the list above
+        seqan::TagList<seqan::SimdVector<int8_t,  32>::Type,
+        seqan::TagList<seqan::SimdVector<int16_t, 16>::Type,
+        seqan::TagList<seqan::SimdVector<int32_t,  8>::Type,
+        seqan::TagList<seqan::SimdVector<int64_t,  4>::Type,
+        seqan::TagList<seqan::SimdVector<uint8_t,  32>::Type,
+        seqan::TagList<seqan::SimdVector<uint16_t, 16>::Type,
+        seqan::TagList<seqan::SimdVector<uint32_t,  8>::Type,
+        seqan::TagList<seqan::SimdVector<uint64_t,  4>::Type
+        #if SEQAN_SIZEOF_MAX_VECTOR >= 64
+        , // Extension of the list above
+        seqan::TagList<seqan::SimdVector<int8_t,  64>::Type,
+        seqan::TagList<seqan::SimdVector<int16_t, 32>::Type,
+        seqan::TagList<seqan::SimdVector<int32_t, 16>::Type,
+        seqan::TagList<seqan::SimdVector<int64_t,  8>::Type,
+        seqan::TagList<seqan::SimdVector<uint8_t,  64>::Type,
+        seqan::TagList<seqan::SimdVector<uint16_t, 32>::Type,
+        seqan::TagList<seqan::SimdVector<uint32_t, 16>::Type,
+        seqan::TagList<seqan::SimdVector<uint64_t,  8>::Type
+        > > > > > > > >
+        #endif
+        > > > > > > > >
+        #endif
+        > > > > > > > >
+        SimdVectorCommonCommonTypes;
+
+SEQAN_TYPED_TEST_CASE(SimdVectorTestCommon, SimdVectorCommonCommonTypes);
+SEQAN_TYPED_TEST_CASE(SimdVectorTestGather, SimdVectorCommonCommonTypes);
+
+SEQAN_DEFINE_TEST(test_simd_types)
+{
+    using namespace seqan;
+
+    // SimdVector16Char
+    static_assert(std::is_same<SimdVector<int8_t, 16>::Type,  SimdVector16SChar>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int16_t, 8>::Type,  SimdVector8Short>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int32_t, 4>::Type,  SimdVector4Int>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int64_t, 2>::Type,  SimdVector2Int64>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint8_t, 16>::Type, SimdVector16UChar>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint16_t, 8>::Type, SimdVector8UShort>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint32_t, 4>::Type, SimdVector4UInt>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint64_t, 2>::Type, SimdVector2UInt64>::value, "should be the same type");
+
+    static_assert(LENGTH<SimdVector4UInt>::VALUE == 4, "128bit register fits 4 int's");
+    static_assert(LENGTH<SimdVector<uint32_t, 4>::Type>::VALUE == 4, "128bit register fits 4 int's");
+    SimdVector<uint32_t, 4>::Type a128 = {0, 1, 2, 3};
+    for (uint32_t i = 0; i < 4; ++i) {
+        // std::cout << i << ": " << a128[i] << " = " << i << std::endl;
+        SEQAN_ASSERT_EQ(a128[i], i);
+    }
+
+    // SimdVector32Char
+#if SEQAN_SIZEOF_MAX_VECTOR >= 32
+    static_assert(std::is_same<SimdVector<int8_t,  32>::Type,  SimdVector32SChar>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int16_t, 16>::Type,  SimdVector16Short>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int32_t,  8>::Type,  SimdVector8Int>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int64_t,  4>::Type,  SimdVector4Int64>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint8_t,  32>::Type, SimdVector32UChar>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint16_t, 16>::Type, SimdVector16UShort>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint32_t,  8>::Type, SimdVector8UInt>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint64_t,  4>::Type, SimdVector4UInt64>::value, "should be the same type");
+
+    static_assert(LENGTH<SimdVector8UInt>::VALUE == 8, "256bit register fits 8 int's");
+    static_assert(LENGTH<SimdVector<uint32_t, 8>::Type>::VALUE == 8, "256bit register fits 8 int's");
+    SimdVector<uint32_t, 8>::Type a256 = {0, 1, 2, 3, 4, 5, 6, 7};
+    for (uint32_t i = 0; i < 8; ++i) {
+        // std::cout << i << ": " << a256[i] << " = " << i << std::endl;
+        SEQAN_ASSERT_EQ(a256[i], i);
+    }
+#endif
+
+#if SEQAN_SIZEOF_MAX_VECTOR >= 64
+    static_assert(std::is_same<SimdVector<int8_t,  64>::Type,  SimdVector64SChar>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int16_t, 32>::Type,  SimdVector32Short>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int32_t, 16>::Type,  SimdVector16Int>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<int64_t,  8>::Type,  SimdVector8Int64>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint8_t,  64>::Type, SimdVector64UChar>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint16_t, 32>::Type, SimdVector32UShort>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint32_t, 16>::Type, SimdVector16UInt>::value, "should be the same type");
+    static_assert(std::is_same<SimdVector<uint64_t,  8>::Type, SimdVector8UInt64>::value, "should be the same type");
+
+    static_assert(LENGTH<SimdVector16UInt>::VALUE == 16, "512bit register fits 16 int's");
+    static_assert(LENGTH<SimdVector<uint32_t, 16>::Type>::VALUE == 16, "512bit register fits 16 int's");
+    SimdVector<uint32_t, 16>::Type a512 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+    for (uint32_t i = 0; i < 16; ++i) {
+        // std::cout << i << ": " << a512[i] << " = " << i << std::endl;
+        SEQAN_ASSERT_EQ(a512[i], i);
+    }
+#endif
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, MetaFunctions)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+
+    // NOTE(marehr): explicit namespace is necessary for msvc 2015:
+    // error C2039: 'VALUE': is not a member of '`global namespace''
+    constexpr auto length = seqan::LENGTH<TSimdVector>::VALUE;
+    using TValue = typename Value<TSimdVector>::Type;
+    typedef typename SimdVector<TValue, length>::Type TSimdVectorNew;
+
+    bool sameType = IsSameType<TSimdVector, TSimdVectorNew>::VALUE;
+    SEQAN_ASSERT(sameType);
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, SizeOf)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u};
+
+    // only on windows are the values unequal
+    SEQAN_ASSERT_GEQ(sizeof(a), sizeof(TValue) * length);
+
+    // on linux we assume that the sizes are equal
+#ifndef STDLIB_VS
+    SEQAN_ASSERT_EQ(sizeof(a), sizeof(TValue) * length);
+#endif
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, SubscriptType)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+    TValue c = a[0];
+
+    bool sameType = IsSameType<TValue, decltype(c)>::VALUE;
+    SEQAN_ASSERT(sameType);
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, ClearVector)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    auto zero = static_cast<TValue>(0);
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    clearVector(a);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)a[i] << " = " << 0 << std::endl;
+        SEQAN_ASSERT_EQ(a[i], zero);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, CreateVector)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    auto scalar = static_cast<TValue>(23);
+    auto a = createVector<TSimdVector>(scalar);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)a[i] << " = " << 23 << std::endl;
+        SEQAN_ASSERT_EQ(a[i], scalar);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, FillVectorConstant)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u};
+
+    fillVector(a, 5);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)a[i] << " = " << i << std::endl;
+        SEQAN_ASSERT_EQ(a[i], static_cast<TValue>(5));
+    }
+}
+
+template <typename TSimdVector, std::size_t... index >
+inline void
+call_fill_vector(TSimdVector & a, std::index_sequence<index...>)
+{
+    seqan::fillVector(a, index...);
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, FillVector)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u};
+
+    // calls seqan::fillVector(a, 0, 1, 2, 3, ..., length-1);
+    call_fill_vector(a, std::make_index_sequence<length>{});
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)a[i] << " = " << i << std::endl;
+        SEQAN_ASSERT_EQ(a[i], static_cast<TValue>(i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, CmpEqual)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    using TBoolValue = decltype(trueValue<TSimdVector>());
+    constexpr auto length = TestFixture::LENGTH;
+
+    TBoolValue false_ = 0,
+               true_ = trueValue<TSimdVector>();
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    // There is never a match for the most instantiations of this test.
+    a[1] = 23;
+    b[1] = 23;
+
+    auto c = cmpEq(a, b);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = (i == 1) ? 23 : (-3 + i * 3);
+        TValue b_i = (i == 1) ? 23 : (length - i);
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " == " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] == b[i] ? true_ : false_);
+        SEQAN_ASSERT_EQ(c[i], a_i == b_i ? true_ : false_);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, CmpGt)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    using TBoolValue = decltype(trueValue<TSimdVector>());
+    constexpr auto length = TestFixture::LENGTH;
+
+    TBoolValue false_ = 0,
+               true_ = trueValue<TSimdVector>();
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = cmpGt(a, b);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " > " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] > b[i] ? true_ : false_);
+        SEQAN_ASSERT_EQ(c[i], a_i > b_i ? true_ : false_);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Max)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = max(a, b);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = max (" << (int)a[i] << ", " << (int)b[i] << ")" << std::endl;
+        SEQAN_ASSERT_EQ(c[i], std::max(a[i], b[i]));
+        SEQAN_ASSERT_EQ(c[i], std::max(a_i, b_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, BitwiseOr)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = a | b;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " | " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] | b[i]);
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a_i | b_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, BitwiseOrAssign)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u}, c{0u};
+    fillVectors(a, b);
+
+    c = a;
+    c |= b;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " | " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] | b[i]);
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a_i | b_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, BitwiseAnd)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = a & b;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " & " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] & b[i]);
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a_i & b_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, BitwiseAndAssign)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u}, c{0u};
+    fillVectors(a, b);
+
+    c = a;
+    c &= b;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " & " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] & b[i]);
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a_i & b_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, BitwiseNot)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = ~a;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = ~" << (int)a[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(~a[i]));
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(~a_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Addition)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = a + b;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " + " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a[i] + b[i]));
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a_i + b_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Subtraction)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = a - b;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " - " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a[i] - b[i]));
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a_i - b_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Multiplication)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = a * b;
+
+    for (size_t i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " * " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a[i] * b[i]));
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a_i * b_i));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Division)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = a / b;
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " / " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] / b[i]);
+        SEQAN_ASSERT_EQ(c[i], a_i / b_i);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, BitwiseAndNot)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = andNot(a, b);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = (~" << (int)a[i] << ") & " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(~a[i] & b[i]));
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(~(-3 + i * 3) & (length - i)));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, ShiftRightLogical)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    // ensure that a >= 0, because (-3) >> 2 has undefined behavior according to
+    // C++ 11 standard.
+    a = a + createVector<TSimdVector>(3);
+
+    auto c = shiftRightLogical(a, 2);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = i * 3;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " >> " << (int)2 << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] >> 2);
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a_i >> 2));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Blend)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    auto c = blend(b, a, cmpGt(a, b));
+
+    for (auto i = 0; i < length; ++i)
+    {
+        TValue a_i = -3 + i * 3, b_i = length - i;
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << " > " << (int)b[i] << " ? " << (int)a[i] << " : " << (int)b[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i] > b[i] ? (TValue)a[i] : (TValue)b[i]);
+        SEQAN_ASSERT_EQ(c[i], a_i > b_i ? a_i : b_i);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Storeu)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, b{0u};
+    fillVectors(a, b);
+
+    TValue c[length];
+    storeu(c, a);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i]);
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(-3 + i * 3));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Load)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, c{0u};
+    fillVectors(a, c);
+
+    alignas(TSimdVector) TValue b[length];
+    storeu(b, a);
+    c = load<TSimdVector>(b);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[i]);
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(-3 + i * 3));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Gather)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    using TValue = typename TestFixture::TValue;
+    constexpr auto length = TestFixture::LENGTH;
+
+    TSimdVector a{0u}, idx{0u};
+    fillVectors(a, idx);
+    reverseIndexSequence(idx, length);
+
+    TValue b[length];
+    storeu(b, a);
+    auto c = gather(b, idx);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[idx[i]] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[idx[i]]);
+        SEQAN_ASSERT_EQ(c[i], a[length - i - 1]);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, ShuffleConstant1)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    constexpr auto length = TestFixture::LENGTH;
+    typedef typename SimdSwizzleVector<TSimdVector>::Type TSimdSwizzleVector;
+
+    TSimdVector a{0u}, b{0u};
+    auto idx = createVector<TSimdSwizzleVector>(1);
+    fillVectors(a, b);
+
+    auto c = shuffleVector(a, idx);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[idx[i]] << ", idx: " << (int)idx[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[idx[i]]);
+        SEQAN_ASSERT_EQ(c[i], a[1]);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, ShuffleConstant2)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    constexpr auto length = TestFixture::LENGTH;
+    typedef typename SimdSwizzleVector<TSimdVector>::Type TSimdSwizzleVector;
+
+    TSimdVector a{0u}, b{0u};
+    auto idx = createVector<TSimdSwizzleVector>(length - 2);
+    fillVectors(a, b);
+
+    auto c = shuffleVector(a, idx);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[idx[i]] << ", idx: " << (int)idx[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[idx[i]]);
+        SEQAN_ASSERT_EQ(c[i], a[length-2]);
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestCommon, Shuffle)
+{
+    using namespace seqan;
+    using TSimdVector = typename TestFixture::TSimdVector;
+    constexpr auto length = TestFixture::LENGTH;
+    typedef typename SimdSwizzleVector<TSimdVector>::Type TSimdSwizzleVector;
+
+    TSimdVector a{0u}, b{0u};
+    TSimdSwizzleVector idx{0u};
+    fillVectors(a, b);
+    reverseIndexSequence(idx, length);
+
+    auto c = shuffleVector(a, idx);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (int)c[i] << " = " << (int)a[idx[i]] << ", idx: " << (int)idx[i] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], a[idx[i]]);
+        SEQAN_ASSERT_EQ(c[i], a[length - i - 1]);
+    }
+}
+
+template <typename TSimdVector, typename TValue, typename TArrayValue>
+inline void test_gather_array()
+{
+    using namespace seqan;
+    constexpr auto length = LENGTH<TSimdVector>::VALUE;
+
+    TSimdVector idx{0u};
+    reverseIndexSequence(idx, length);
+
+    TArrayValue a[2*length];
+
+    // fill gather array
+    for (auto i = 0; i < 2*length; ++i)
+    {
+        a[i] = (i-1)*3;
+    }
+
+    auto c = gather(a, idx);
+
+    for (auto i = 0; i < length; ++i)
+    {
+        // std::cout << i << " / " << length << ": " << (TValue)c[i] << " = " << (TValue)a[idx[i]] << std::endl;
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a[idx[i]]));
+        SEQAN_ASSERT_EQ(c[i], static_cast<TValue>(a[length - i - 1]));
+    }
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestGather, CharArray)
+{
+    test_gather_array<
+        typename TestFixture::TSimdVector,
+        typename TestFixture::TValue,
+        int8_t
+    >();
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestGather, ShortArray)
+{
+    test_gather_array<
+        typename TestFixture::TSimdVector,
+        typename TestFixture::TValue,
+        int16_t
+    >();
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestGather, IntArray)
+{
+    test_gather_array<
+        typename TestFixture::TSimdVector,
+        typename TestFixture::TValue,
+        int32_t
+    >();
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestGather, LongArray)
+{
+    test_gather_array<
+        typename TestFixture::TSimdVector,
+        typename TestFixture::TValue,
+        int64_t
+    >();
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestGather, UCharArray)
+{
+    test_gather_array<
+        typename TestFixture::TSimdVector,
+        typename TestFixture::TValue,
+        uint8_t
+    >();
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestGather, UShortArray)
+{
+    test_gather_array<
+        typename TestFixture::TSimdVector,
+        typename TestFixture::TValue,
+        uint16_t
+    >();
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestGather, UIntArray)
+{
+    test_gather_array<
+        typename TestFixture::TSimdVector,
+        typename TestFixture::TValue,
+        uint32_t
+    >();
+}
+
+SEQAN_TYPED_TEST(SimdVectorTestGather, ULongArray)
+{
+    test_gather_array<
+        typename TestFixture::TSimdVector,
+        typename TestFixture::TValue,
+        uint64_t
+    >();
+}
+
+#ifdef __SSE4_1__
+
+SEQAN_DEFINE_TEST(test_simd_transpose_8x8)
+{
+    seqan::test_matrix_transpose<8, seqan::SimdVector<unsigned char, 8>::Type>();
+}
+
+SEQAN_DEFINE_TEST(test_simd_transpose_16x16)
+{
+    seqan::test_matrix_transpose<16, seqan::SimdVector<unsigned char, 16>::Type>();
+}
+
+#endif  // #ifdef __SSE4_1__
+#ifdef __AVX2__
+
+SEQAN_DEFINE_TEST(test_simd_transpose_32x32)
+{
+    seqan::test_matrix_transpose<32, seqan::SimdVector<unsigned char, 32>::Type >();
+}
+
+#endif  // #ifdef __AVX2__
+#endif  // SEQAN_SIMD_ENABLED
+
+#endif  // #ifndef SEQAN_CORE_TESTS_SIMD_TEST_SIMD_VECTOR_H_
diff --git a/util/cmake/FindSDE.cmake b/util/cmake/FindSDE.cmake
new file mode 100644
index 0000000..88b9f18
--- /dev/null
+++ b/util/cmake/FindSDE.cmake
@@ -0,0 +1,81 @@
+# ============================================================================
+#                  SeqAn - The Library for Sequence Analysis
+# ============================================================================
+# Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+#       its contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+# ============================================================================
+# Author: Marcel Ehrhardt <marcel.ehrhardt at fu-berlin.de>
+# ============================================================================
+#
+#.rst:
+# FindSDE
+# ---------
+#
+# Try to find Intel® Software Development Emulator
+#
+# Once done this will define
+#
+# ::
+#
+#   SDE_FOUND - system has Intel® SDE
+#   SDE_EXECUTABLE - the Intel® SDE executable (full path)
+#   SDE_VERSION_STRING - the version of Intel® SDE found
+
+set(SDE_EXECUTABLE)
+set(SDE_VERSION_STRING)
+
+# first try 64bit and then 32bit version of sde
+foreach(sde_exec "sde64" "sde")
+    find_program(SDE_EXECUTABLE
+        NAMES "${sde_exec}"
+        PATHS
+            /usr/bin
+            /usr/local/bin
+            /opt/local/bin
+        DOC "Intel Software Development Emulator"
+    )
+
+    if (SDE_EXECUTABLE)
+      execute_process(COMMAND "${SDE_EXECUTABLE}" "--version" OUTPUT_VARIABLE SDE_OUTPUT_VERSION)
+      if (SDE_OUTPUT_VERSION MATCHES "Software Development Emulator")
+          string(REGEX REPLACE ".*Software Development Emulator.*Version:[ ]*([0-9]+\\.[^ ]+).*" "\\1" SDE_VERSION_STRING "${SDE_OUTPUT_VERSION}")
+          break()
+      endif()
+    endif()
+endforeach()
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(
+    SDE
+    FOUND_VAR SDE_FOUND
+    REQUIRED_VARS SDE_EXECUTABLE SDE_VERSION_STRING
+    VERSION_VAR SDE_VERSION_STRING
+    FAIL_MESSAGE "Could NOT find SDE: Intel(R) Software Development Emulator (sde)"
+)
+
+mark_as_advanced(SDE_EXECUTABLE)
diff --git a/util/cmake/FindUmesimd.cmake b/util/cmake/FindUmesimd.cmake
new file mode 100644
index 0000000..4ad0ed5
--- /dev/null
+++ b/util/cmake/FindUmesimd.cmake
@@ -0,0 +1,65 @@
+# ============================================================================
+#                  SeqAn - The Library for Sequence Analysis
+# ============================================================================
+# Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+#       its contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+# ============================================================================
+# Author: Marcel Ehrhardt <marcel.ehrhardt at fu-berlin.de>
+# ============================================================================
+#
+#.rst:
+# FindUmesimd
+# -----------
+#
+# Try to find UME::SIMD includes
+#
+# Once done this will define
+#
+# ::
+#
+#   UMESIMD_FOUND - system has UME::SIMD
+#   UMESIMD_INCLUDE_DIR - the UME::SIMD include directory
+#   UMESIMD_VERSION_STRING - the version of UME::SIMD found
+
+find_path(UMESIMD_CHILD_INCLUDE_DIR UMESimd.h PATH_SUFFIXES umesimd)
+
+if (UMESIMD_CHILD_INCLUDE_DIR AND EXISTS "${UMESIMD_CHILD_INCLUDE_DIR}/UMESimd.h")
+    get_filename_component(UMESIMD_INCLUDE_DIR ${UMESIMD_CHILD_INCLUDE_DIR} DIRECTORY)
+
+    file(STRINGS "${UMESIMD_CHILD_INCLUDE_DIR}/UMESimd.h" UMESIMD_H REGEX "#define UME_SIMD_VERSION_(MAJOR|MINOR|PATCH)")
+    string(REGEX REPLACE "#define UME_SIMD_VERSION_(MAJOR|MINOR|PATCH) " "" UMESIMD_VERSION_STRING "${UMESIMD_H}")
+    string(REGEX REPLACE ";" "." UMESIMD_VERSION_STRING "${UMESIMD_VERSION_STRING}")
+endif ()
+
+# set UMESIMD_FOUND to TRUE if all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(
+    Umesimd
+    REQUIRED_VARS UMESIMD_INCLUDE_DIR
+    VERSION_VAR UMESIMD_VERSION_STRING)
+
+mark_as_advanced(UMESIMD_INCLUDE_DIR)
diff --git a/util/cmake/SeqAnBuildSystem.cmake b/util/cmake/SeqAnBuildSystem.cmake
index a9f6e74..e705b0e 100644
--- a/util/cmake/SeqAnBuildSystem.cmake
+++ b/util/cmake/SeqAnBuildSystem.cmake
@@ -227,15 +227,16 @@ macro (seqan_build_system_init)
     endif ()
 
     # Architecture.
-    if (NOT SEQAN_64BIT_TARGET_PLATFORM)
+    if ((NOT SEQAN_64BIT_TARGET_PLATFORM) OR COMPILER_MSVC)
         set (SEQAN_ARCH_SSE4 FALSE)
         set (SEQAN_ARCH_AVX2 FALSE)
+        set (SEQAN_ARCH_AVX512_KNL FALSE)
+        set (SEQAN_ARCH_AVX512_SKX FALSE)
+        set (SEQAN_ARCH_AVX512_CNL FALSE)
     endif ()
 
     if (COMPILER_MSVC)
         set (SEQAN_STATIC_APPS FALSE)
-        set (SEQAN_ARCH_SSE4 FALSE)
-        set (SEQAN_ARCH_AVX2 FALSE)
         set (SEQAN_ARCH_NATIVE FALSE)
     endif ()
 
@@ -248,8 +249,9 @@ macro (seqan_build_system_init)
         endif ()
     endif ()
 
-    # Enable SSE4 if AVX2 is set.
-    if (SEQAN_ARCH_AVX2)
+    # Enable SSE4 if AVX[\d]+ is set. (Other parts in our build system expect it
+    # to be set and it is basically the synonym for 'SIMD is enabled')
+    if (SEQAN_ARCH_AVX2 OR SEQAN_ARCH_AVX512_KNL OR SEQAN_ARCH_AVX512_SKX OR SEQAN_ARCH_AVX512_CNL)
         set (SEQAN_ARCH_SSE4 TRUE)
     endif ()
 
@@ -265,21 +267,31 @@ macro (seqan_build_system_init)
         if (COMPILER_LINTEL)
             set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -ipo -no-prec-div -fp-model fast=2 -xHOST")
         endif ()
-    else ()
-        if (SEQAN_ARCH_SSE4)
-            if (SEQAN_ARCH_AVX2)
-                message (STATUS "Building optimized binaries up to AVX2 and POPCNT.")
-                set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -mavx -mavx2")
-            else ()
-                message (STATUS "Building optimized binaries up to SSE4 and POPCNT.")
-            endif ()
-            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -mmmx -msse -msse2 -msse3 -mssse3 -msse4")
-            if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
-                set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -mpopcnt")
-            endif ()
-            if (COMPILER_LINTEL)
-                set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -ipo -no-prec-div -fp-model fast=2")
-            endif ()
+    elseif (SEQAN_ARCH_SSE4)
+        include (SeqAnSimdUtility)
+
+        if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -mpopcnt")
+        endif ()
+        if (COMPILER_LINTEL)
+            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -ipo -no-prec-div -fp-model fast=2")
+        endif ()
+
+        if (SEQAN_ARCH_AVX512_CNL)
+            message (STATUS "Building optimized binaries up to AVX512 CNL and POPCNT.")
+            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_AVX512_CNL_OPTIONS}")
+        elseif (SEQAN_ARCH_AVX512_SKX)
+            message (STATUS "Building optimized binaries up to AVX512 SKX and POPCNT.")
+            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_AVX512_SKX_OPTIONS}")
+        elseif (SEQAN_ARCH_AVX512_KNL)
+            message (STATUS "Building optimized binaries up to AVX512 KNL and POPCNT.")
+            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_AVX512_KNL_OPTIONS}")
+        elseif (SEQAN_ARCH_AVX2)
+            message (STATUS "Building optimized binaries up to AVX2 and POPCNT.")
+            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_AVX2_OPTIONS}")
+        else ()
+            message (STATUS "Building optimized binaries up to SSE4 and POPCNT.")
+            set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} ${SEQAN_SIMD_SSE4_OPTIONS}")
         endif ()
     endif ()
     # TODO(h-2): for icc on windows, replace the " -" in SEQAN_CXX_FLAGS with " /"
diff --git a/util/cmake/SeqAnContribs.cmake b/util/cmake/SeqAnContribs.cmake
index 77eb0ed..16c3e6a 100644
--- a/util/cmake/SeqAnContribs.cmake
+++ b/util/cmake/SeqAnContribs.cmake
@@ -36,7 +36,7 @@
 
 if (WIN32)
   # For all contrib versions...
-  foreach (_SEQAN_CONTRIB_VERSION D20160115)
+  foreach (_SEQAN_CONTRIB_VERSION D20170601 D20160115)
     set (_SEQAN_CONTRIB_DIR "seqan-contrib-${_SEQAN_CONTRIB_VERSION}")
 
 	  # Determine architecture for the precompiled contribs.
diff --git a/util/cmake/SeqAnSimdUtility.cmake b/util/cmake/SeqAnSimdUtility.cmake
new file mode 100644
index 0000000..4d22d6f
--- /dev/null
+++ b/util/cmake/SeqAnSimdUtility.cmake
@@ -0,0 +1,611 @@
+# ============================================================================
+#                  SeqAn - The Library for Sequence Analysis
+# ============================================================================
+# Copyright (c) 2006-2016, Knut Reinert, FU Berlin
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of Knut Reinert or the FU Berlin nor the names of
+#       its contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+# ============================================================================
+# Author: Marcel Ehrhardt <marcel.ehrhardt at fu-berlin.de>
+# ============================================================================
+#
+#.rst:
+# SeqanSimdUtility
+# ----------------
+#
+# Utility to create binaries for different SIMD implementations and target
+# architectures. Disables architectures if the compiler can't handle it or bugs
+# in the code generation are known.
+#
+# .. code-block:: cmake
+#
+#   add_executable (
+#     test_simd_vector
+#     test_simd_vector.cpp
+#     test_simd_vector.h)
+#   target_link_libraries (test_simd_vector ${SEQAN_LIBRARIES})
+#   add_simd_platform_tests(test_simd_vector)
+#
+# Could build the following binaries and add tests for them
+#
+# ::
+#
+#   Built target test_simd_vector
+#   Built target test_simd_vector_sse4
+#   Built target test_simd_vector_avx2
+#   Built target test_simd_vector_umesimd
+#   Built target test_simd_vector_umesimd_sse4
+#   Built target test_simd_vector_umesimd_avx2
+#   Built target test_simd_vector_umesimd_avx512_knl
+#
+# Functions
+# +++++++++++
+#
+# ::
+#
+#   add_simd_platform_tests(target)
+#       - builds target on different simd implementations and architectures
+#       - adds targets which use the seqan::simd default implementation
+#       - adds targets which use the UME::SIMD library instead of the seqan
+#         default implementation if UMESIMD_FOUND is set
+#       - adds tests for different architectures if the Intel® Software
+#         Development Emulator could be found, i.e. if SDE_FOUND is set
+#
+#         NOTE: You don't have to add_test the target (e.g. test_simd_vector)
+#         itself, because it will be done by this function.
+#
+#   add_simd_executables(target blacklist) [not required to use explicitly]
+#       - adds executables for sse4, avx2, etc. as `target`_sse4, `target`_avx2,
+#         etc. (Will clone the SOURCE, FLAGS and other properties from `target`)
+#       - blacklist: list of architectures that shouldn't be added (e.g. sse4,
+#         avx2, avx512_knl, avx512_skx, avx512_cnl)
+#
+#   add_simd_tests(target blacklist) [not required to use explicitly]
+#       - adds tests for executables (targets) specified by add_simd_executables
+#       - blacklist: list of architectures which executables shouldn't be tested
+#         (e.g. sse4, avx2, avx512_knl, avx512_skx, avx512_cnl)
+#
+
+find_package (SeqAn CONFIG REQUIRED)
+find_package (SDE)
+find_package (Umesimd)
+
+include(CheckCXXSourceCompiles)
+include(CheckCXXSourceRuns)
+
+set(SEQAN_SIMD_UTILITY_VERBOSE OFF)
+set(SEQAN_SIMD_SUPPORTED_EXTENSIONS "sse4;avx2;avx512_knl;avx512_skx;avx512_cnl")
+
+if (COMPILER_MSVC)
+    set(SEQAN_SIMD_SSE4_FLAGS "/arch:AVX")
+    set(SEQAN_SIMD_AVX2_FLAGS "/arch:AVX2")
+    set(SEQAN_SIMD_AVX512_KNL_FLAGS "")
+    set(SEQAN_SIMD_AVX512_SKX_FLAGS "")
+    set(SEQAN_SIMD_AVX512_CNL_FLAGS "")
+elseif (COMPILER_WINTEL)
+    set(SEQAN_SIMD_SSE4_FLAGS "/QxSSE4.2")
+    set(SEQAN_SIMD_AVX2_FLAGS "/QxCORE-AVX2")
+    set(SEQAN_SIMD_AVX512_KNL_FLAGS "/QxMIC-AVX512")
+    set(SEQAN_SIMD_AVX512_SKX_FLAGS "/QxCORE-AVX512")
+    set(SEQAN_SIMD_AVX512_CNL_FLAGS "/QxCORE-AVX512")
+elseif (COMPILER_LINTEL)
+    set(SEQAN_SIMD_SSE4_FLAGS "-xSSE4.2")
+    set(SEQAN_SIMD_AVX2_FLAGS "-xCORE-AVX2")
+    set(SEQAN_SIMD_AVX512_KNL_FLAGS "-xMIC-AVX512")
+    set(SEQAN_SIMD_AVX512_SKX_FLAGS "-xCORE-AVX512")
+    set(SEQAN_SIMD_AVX512_CNL_FLAGS "-xCORE-AVX512")
+else()
+    set(SEQAN_SIMD_SSE4_FLAGS "-msse4")
+    set(SEQAN_SIMD_AVX2_FLAGS "-mavx2")
+    set(SEQAN_SIMD_AVX512_KNL_FLAGS "-mavx512f -mavx512cd -mavx512er -mavx512pf")
+    set(SEQAN_SIMD_AVX512_SKX_FLAGS "-mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl")
+    set(SEQAN_SIMD_AVX512_CNL_FLAGS "${SEQAN_SIMD_AVX512_SKX_FLAGS} -mavx512ifma -mavx512vbmi")
+endif()
+
+# offer flags (string) as list for functions like target_compile_options
+string (REPLACE " " ";" SEQAN_SIMD_SSE4_OPTIONS "${SEQAN_SIMD_SSE4_FLAGS}")
+string (REPLACE " " ";" SEQAN_SIMD_AVX2_OPTIONS "${SEQAN_SIMD_AVX2_FLAGS}")
+string (REPLACE " " ";" SEQAN_SIMD_AVX512_KNL_OPTIONS "${SEQAN_SIMD_AVX512_KNL_FLAGS}")
+string (REPLACE " " ";" SEQAN_SIMD_AVX512_SKX_OPTIONS "${SEQAN_SIMD_AVX512_SKX_FLAGS}")
+string (REPLACE " " ";" SEQAN_SIMD_AVX512_CNL_OPTIONS "${SEQAN_SIMD_AVX512_CNL_FLAGS}")
+
+set(SEQAN_SIMD_SSE4_SDE_OPTIONS "-snb")
+set(SEQAN_SIMD_AVX2_SDE_OPTIONS "-hsw")
+set(SEQAN_SIMD_AVX512_KNL_SDE_OPTIONS "-knl")
+set(SEQAN_SIMD_AVX512_SKX_SDE_OPTIONS "-skx")
+set(SEQAN_SIMD_AVX512_CNL_SDE_OPTIONS "-cnl")
+
+set(SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS)
+set(SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD)
+set(SEQAN_SIMD_HOST_CPU_SUPPORTS)
+
+set(SEQAN_SIMD_SSE4_SOURCE
+"#include <cstdint>
+#include <immintrin.h>
+#include <iostream>
+#include <random>
+
+int main() {
+  std::random_device r;
+  std::default_random_engine e(r());
+  std::uniform_int_distribution<int32_t> d(1, 10);
+
+  alignas(16) int32_t t[]{0,0,0,0};
+  volatile auto a = _mm_set_epi32(d(e),d(e),d(e),d(e));
+  volatile auto b = _mm_set_epi32(d(e),d(e),d(e),d(e));
+  volatile auto z = _mm_max_epi32(a, b);
+  _mm_store_si128((__m128i*)t, z);
+  std::cout << \"(\" << t[0] << \", \" << t[1] << \", \" << t[2] << \", \" << t[3] << \")\" << std::endl;
+  return 0;
+}")
+
+set(SEQAN_SIMD_AVX2_SOURCE
+"#include <cstdint>
+#include <immintrin.h>
+#include <iostream>
+#include <random>
+
+int main() {
+  std::random_device r;
+  std::default_random_engine e(r());
+  std::uniform_int_distribution<int32_t> d(1, 10);
+
+  alignas(32) int64_t t[]{0,0,0,0};
+  volatile auto a = _mm256_set_epi64x(d(e),d(e),d(e),d(e));
+  volatile auto b = _mm256_set_epi64x(d(e),d(e),d(e),d(e));
+  volatile auto z = _mm256_add_epi64(a, b);
+  _mm256_store_si256((__m256i*)t, z);
+  std::cout << \"(\" << t[0] << \", \" << t[1] << \", \" << t[2] << \", \" << t[3] << \")\" << std::endl;
+  return 0;
+}")
+
+set(SEQAN_SIMD_AVX512_KNL_SOURCE
+"#include <cstdint>
+#include <immintrin.h>
+#include <iostream>
+
+int main() {
+  alignas(64) uint64_t s[]{9,9,9,9,9,9,9,9};
+  alignas(64) uint64_t t[]{0,0,0,0,0,0,0,0};
+
+  // gcc 4.9 does not know _mm512_cmpgt_epu64_mask
+  volatile auto a = _mm512_setr_epi64(7,6,5,4,3,2,1,0);
+  volatile auto m = _mm512_cmpgt_epu64_mask(a, _mm512_set1_epi64(4)); // m = a > 4
+  volatile auto z = _mm512_mask_load_epi64(a, m, s); // (a > 4) ? s : a
+  _mm512_store_epi64(t, z);
+
+  // (9, 9, 9, 4, 3, 2, 1, 0)
+  std::cout << \"(\" << t[0] << \", \" << t[1] << \", \" << t[2] << \", \" << t[3] << \", ...)\" << std::endl;
+  return 0;
+}")
+
+set(SEQAN_SIMD_AVX512_SKX_SOURCE "${SEQAN_SIMD_AVX512_KNL_SOURCE}")
+set(SEQAN_SIMD_AVX512_CNL_SOURCE "${SEQAN_SIMD_AVX512_KNL_SOURCE}")
+
+set(SEQAN_SIMD_SEQANSIMD_SOURCE
+"#include <cstdint>
+using int32x4_t = int32_t __attribute__ ((__vector_size__(4 * sizeof(int32_t)))); // SSE4 = 128bit
+using int32x8_t = int32_t __attribute__ ((__vector_size__(8 * sizeof(int32_t)))); // AVX2 = 256bit
+
+// gcc 4.9 bug (-fabi-version=6 (or =0) avoids this error with a change in mangling)
+template <typename vector_t>
+struct LENGTH;
+
+template <>
+struct LENGTH<int32x4_t>{
+    static const std::size_t VALUE = 4;
+};
+
+template <>
+struct LENGTH<int32x8_t>{
+    static const std::size_t VALUE = 8;
+};
+
+// icc 16.0.0, 16.0.1 bug
+template <typename TSimdVector, typename TValue>
+void assign(TSimdVector & a, int index, TValue value) { a[index] = value; }
+
+// icc >= 16.0.0 & <17.0.2 bug
+struct simd_t { int32x4_t simd_vector; };
+
+namespace ns {
+template <typename T>
+T & value(T * me) { return *me; }
+}
+
+template <typename value_t>
+void destruct(value_t * p) { }
+
+template <typename value_t>
+struct string_t {
+    value_t * value;
+
+    template <typename T1>
+    bool static assert(const T1 & value1, const T1 & value2) { return value1 <= value2; }
+
+    string_t() : value(0) { assert(value, value); }
+    ~string_t() { destruct(&ns::value(value)); }
+};
+
+template <typename value_t>
+struct holder_t {
+    value_t * value;
+
+    holder_t() { value = new value_t; }
+    ~holder_t() { delete value; }
+};
+
+struct matrix_t {  holder_t<string_t<simd_t>> cells; };
+
+int main() {
+  int32x4_t a{0,1,2,3}, b{4,3,2,1};
+  int32x8_t x{0,1,2,3,4,5,6,7}, y{4,3,2,1,0,-1,-2,-3};
+  auto c = a + b;
+  auto z = x + y;
+
+  // gcc 4.9 bug
+  constexpr auto length = LENGTH<int32x8_t>::VALUE;
+
+  // icc 16.0.0, 16.0.1 bug
+  assign(a, 0, 4);
+
+  // icc >= 16.0.0 & <17.0.2 bug
+  holder_t<matrix_t> matrix;
+  return 0;
+}")
+
+set(SEQAN_SIMD_SEQANSIMD_AVX512_SKX_SOURCE
+"#include <x86intrin.h>
+#include <iostream>
+using int8x32_t = signed char __attribute__ ((__vector_size__(32)));
+unsigned length = sizeof(int8x32_t) / sizeof(char);
+
+int main() {
+  // clang bug 4.0.0, https://bugs.llvm.org//show_bug.cgi?id=31731
+  // -std=c++14 -mavx512bw -O3
+  int8x32_t a{}, b{};
+  for (auto i = 0u; i < length; ++i) { a[i] = i-1; b[i] = -i; }
+
+  auto c = a < b;
+  for(auto i = 0u; i < length; ++i)
+    std::cout << (int)c[i] << std::endl;
+
+  return 0;
+}")
+
+# list1 and list2
+macro(list_intersect output list1 list2)
+    set(${output})
+    foreach(item ${list1})
+        if (";${list2};" MATCHES ";${item};")
+            list(APPEND ${output} "${item}")
+        endif()
+    endforeach()
+endmacro()
+
+# list1\list2 = list1 and not list2
+macro(list_complement output list1 list2)
+    set(${output})
+    foreach(item ${list1})
+        if (NOT(";${list2};" MATCHES ";${item};"))
+            list(APPEND ${output} "${item}")
+        endif()
+    endforeach()
+endmacro()
+
+# Returns list of all simd extension prior to `simd_ext`
+macro(simd_list_version_less output simd_ext)
+  set(${output})
+
+  foreach(item ${SEQAN_SIMD_SUPPORTED_EXTENSIONS})
+      if (";${item};" MATCHES ";${simd_ext};")
+          break()
+      endif()
+      list(APPEND ${output} "${item}")
+  endforeach()
+endmacro()
+
+# Returns list of all simd extension after to `simd_ext`
+macro(simd_list_version_greater output simd_ext)
+  set(${output})
+  simd_list_version_less(${output} "${simd_ext}")
+  set(${output} ${${output}} "${simd_ext}")
+  list_complement(${output} "${SEQAN_SIMD_SUPPORTED_EXTENSIONS}" "${${output}}")
+endmacro()
+
+# simd specialized try-compile macro
+macro(check_cxx_simd_source_runs SOURCE VAR)
+    if(NOT DEFINED "${VAR}")
+        # empty flags means that this simd extension is not supported by the compiler
+        if (CMAKE_REQUIRED_FLAGS)
+            # -O3 is needed to trigger a compiler bug on clang 4.0.0
+            if (COMPILER_GCC OR COMPILER_CLANG OR COMPILER_LINTEL)
+                set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -O3")
+            endif()
+
+            # CMAKE_REQUIRED_QUIET available since cmake 3.1.0
+            set(CMAKE_REQUIRED_QUIET ON)
+            check_cxx_source_runs("${SOURCE}" ${VAR})
+            set(CMAKE_REQUIRED_QUIET OFF)
+        endif()
+
+        message(STATUS "Performing Test ${VAR}")
+        if (NOT CMAKE_REQUIRED_FLAGS)
+            set(${VAR} 0 CACHE INTERNAL "Test ${VAR}")
+            message(STATUS "Performing Test ${VAR} - No flags to enable simd architecture")
+        elseif (${VAR})
+            message(STATUS "Performing Test ${VAR} - Success (Compiled & Host CPU support)")
+        elseif (NOT ${VAR}_COMPILED)
+            message(STATUS "Performing Test ${VAR} - Failed")
+        elseif (NOT ${VAR})
+            message(STATUS "Performing Test ${VAR} - Success (Compiled)")
+        endif()
+    endif()
+endmacro()
+
+# detect simd support and cache it
+macro(detect_simd_support)
+    # Executing simd on 32bit architectures has issues
+    if (NOT DEFINED SEQAN_SIMD_DETECTED AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+        message(STATUS "SIMD acceleration is only available on 64bit systems")
+        set(SEQAN_SIMD_DETECTED 1 CACHE INTERNAL "Detected SEQAN_SIMD_DETECTED")
+        set(SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS "" CACHE INTERNAL "Test SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS")
+        set(SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD "" CACHE INTERNAL "Test SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD")
+        set(SEQAN_SIMD_HOST_CPU_SUPPORTS "" CACHE INTERNAL "Test SEQAN_SIMD_HOST_CPU_SUPPORTS")
+    elseif (NOT DEFINED SEQAN_SIMD_DETECTED)
+        # First try to compile AND run e.g. SEQAN_SIMD_SSE4_SOURCE, otherwise try to
+        # only compile the program
+        foreach(simd_ext ${SEQAN_SIMD_SUPPORTED_EXTENSIONS})
+            string(TOUPPER ${simd_ext} SIMD_EXT)
+            set(CMAKE_REQUIRED_FLAGS "${SEQAN_SIMD_${SIMD_EXT}_FLAGS}")
+            check_cxx_simd_source_runs("${SEQAN_SIMD_${SIMD_EXT}_SOURCE}" ${SIMD_EXT}_SOURCE_RUNS)
+
+            if (${SIMD_EXT}_SOURCE_RUNS)
+                list(APPEND SEQAN_SIMD_HOST_CPU_SUPPORTS "${simd_ext}")
+            endif()
+
+            if (${SIMD_EXT}_SOURCE_RUNS_COMPILED)
+                list(APPEND SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS "${simd_ext}")
+            elseif (CMAKE_REQUIRED_FLAGS)
+                message(STATUS "=> Abort simd detection of newer instruction sets")
+                break()
+            endif()
+        endforeach()
+
+        # test seqan simd
+        check_cxx_source_compiles("${SEQAN_SIMD_SEQANSIMD_SOURCE}" SEQAN_SIMD_SEQANSIMD_SUPPORTED)
+
+        # try-compile known compiler crashes/errors with seqan-simd and exclude them
+        if (SEQAN_SIMD_SEQANSIMD_SUPPORTED)
+            set(CMAKE_REQUIRED_FLAGS "${SEQAN_SIMD_AVX512_SKX_FLAGS}")
+            check_cxx_simd_source_runs("${SEQAN_SIMD_SEQANSIMD_AVX512_SKX_SOURCE}" SEQANSIMD_AVX512_SKX_SOURCE_RUNS)
+
+            if (SEQANSIMD_AVX512_SKX_SOURCE_RUNS_COMPILED)
+                set(_SEQANSIMD_SUPPORTED "${SEQAN_SIMD_SUPPORTED_EXTENSIONS}")
+            else ()
+                simd_list_version_less(_SEQANSIMD_SUPPORTED "avx512_skx")
+            endif()
+        endif()
+
+        # seqan-simd also uses intrinsics, so exclude those that failed the intrinsic try-compile
+        list_intersect(SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD "${_SEQANSIMD_SUPPORTED}" "${SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS}")
+
+        # cache results
+        set(SEQAN_SIMD_DETECTED 1 CACHE INTERNAL "Detected SEQAN_SIMD_DETECTED")
+        set(SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS "${SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS}" CACHE INTERNAL "Test SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS")
+        set(SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD "${SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD}" CACHE INTERNAL "Test SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD")
+        set(SEQAN_SIMD_HOST_CPU_SUPPORTS "${SEQAN_SIMD_HOST_CPU_SUPPORTS}" CACHE INTERNAL "Test SEQAN_SIMD_HOST_CPU_SUPPORTS")
+
+        if(SEQAN_SIMD_UTILITY_VERBOSE)
+            message(STATUS "SEQAN_SIMD_SEQANSIMD_SUPPORTED: ${SEQAN_SIMD_SEQANSIMD_SUPPORTED}")
+            message(STATUS "SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS: ${SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS}")
+            message(STATUS "SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD: ${SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD}")
+            message(STATUS "SEQAN_SIMD_HOST_CPU_SUPPORTS: ${SEQAN_SIMD_HOST_CPU_SUPPORTS}")
+        endif()
+
+        unset(CMAKE_REQUIRED_FLAGS)
+        unset(SIMD_EXT)
+        unset(_SEQANSIMD_SUPPORTED)
+    endif()
+endmacro()
+
+macro(transfer_target_property property source_target target_target)
+    get_target_property(_property_value ${source_target} ${property})
+
+    # message(STATUS "${source_target}: ${property} == ${_property_value}")
+
+    if(_property_value)
+        # message(STATUS "${target_target}: set ${property} = ${_property_value}")
+        set_target_properties(${target_target} PROPERTIES ${property} "${_property_value}")
+    endif()
+endmacro()
+
+macro(clone_target source_target target_target)
+    get_target_property(_SOURCES ${source_target} SOURCES)
+
+    # message(STATUS "transfer properties from ${source_target} to ${target_target}")
+    # message(STATUS "${source_target}: SOURCES == ${_SOURCES}")
+    # message(STATUS "${target_target}: set SOURCES = ${_SOURCES}")
+    add_executable(${target_target} ${_SOURCES})
+
+    # https://cmake.org/cmake/help/v3.4/manual/cmake-properties.7.html#properties-on-targets
+    set(properies "SOURCE_DIR;COMPILE_DEFINITIONS;COMPILE_FEATURES;COMPILE_FLAGS"
+                "COMPILE_OPTIONS;LINK_LIBRARIES;LINK_FLAGS;CXX_EXTENSIONS"
+                "CXX_STANDARD;CXX_STANDARD_REQUIRED;FOLDER;INCLUDE_DIRECTORIES")
+
+    foreach(property ${properies})
+        transfer_target_property(${property} ${source_target} ${target_target})
+    endforeach()
+endmacro(clone_target)
+
+macro(add_simd_executables target blacklist)
+    foreach(simd_ext ${SEQAN_SIMD_SUPPORTED_EXTENSIONS})
+        string(TOUPPER ${simd_ext} SIMD_EXT)
+        if (NOT (";${blacklist};" MATCHES ";${simd_ext};"))
+            # i.e. clone_target(${target} "${target}_avx2")
+            clone_target(${target} "${target}_${simd_ext}")
+            # i.e. target_compile_options("${target}_avx2" PRIVATE "${SEQAN_SIMD_AVX2_OPTIONS}")
+            target_compile_options("${target}_${simd_ext}" PRIVATE "${SEQAN_SIMD_${SIMD_EXT}_OPTIONS}")
+
+            # empty FLAGS means no support for this simd architecture
+            if (NOT SEQAN_SIMD_${SIMD_EXT}_OPTIONS)
+                message(STATUS "${simd_ext} not supported on ${CMAKE_CXX_COMPILER_ID} (no flags)")
+            endif()
+        endif()
+        unset(SIMD_EXT)
+    endforeach()
+endmacro(add_simd_executables)
+
+macro(add_simd_tests target blacklist)
+    add_test(NAME "test_${target}" COMMAND $<TARGET_FILE:${target}>)
+
+    # simd extensions supported by the host CPU
+    foreach(simd_ext ${SEQAN_SIMD_HOST_CPU_SUPPORTS})
+        string(TOUPPER ${simd_ext} SIMD_EXT)
+        if (TARGET "${target}_${simd_ext}" AND NOT (";${blacklist};" MATCHES ";${simd_ext};"))
+            # expands as
+            # add_test(NAME "test_test_simd_vector_sse4" COMMAND /usr/bin/sde64 -snb -- $<TARGET_FILE:test_simd_vector_sse4>)
+            add_test(NAME "test_${target}_${simd_ext}_host" COMMAND $<TARGET_FILE:${target}_${simd_ext}>)
+        endif()
+    endforeach()
+
+    if (SDE_FOUND)
+        foreach(simd_ext ${SEQAN_SIMD_SUPPORTED_EXTENSIONS})
+            string(TOUPPER ${simd_ext} SIMD_EXT)
+            if (TARGET "${target}_${simd_ext}" AND NOT (";${blacklist};" MATCHES ";${simd_ext};"))
+                # expands as
+                # add_test(NAME "test_test_simd_vector_sse4" COMMAND /usr/bin/sde64 -snb -- $<TARGET_FILE:test_simd_vector_sse4>)
+                add_test(NAME "test_${target}_${simd_ext}_sde" COMMAND ${SDE_EXECUTABLE} ${SEQAN_SIMD_${SIMD_EXT}_SDE_OPTIONS} -- $<TARGET_FILE:${target}_${simd_ext}>)
+            endif()
+        endforeach()
+    else ()
+        message (STATUS "Intel Software Development Emulator not found, not building platform emulated tests.")
+    endif()
+endmacro(add_simd_tests)
+
+macro(add_simd_platform_tests target)
+    if (UMESIMD_FOUND)
+        clone_target("${target}" "${target}_umesimd")
+        target_include_directories("${target}_umesimd" PUBLIC "${UMESIMD_INCLUDE_DIR}")
+        target_compile_definitions("${target}_umesimd" PUBLIC SEQAN_UMESIMD_ENABLED=1)
+    endif()
+
+    # We don't disable AVX512 even though seqan-simd doesn't support AVX512 (it
+    # will fallback to AVX2 in source code), but it replaces some intrinsics
+    # with ones introduced in AVX512.
+    set(seqansimd_compile_blacklist "")
+    set(seqansimd_test_blacklist "")
+
+    set(umesimd_compile_blacklist "")
+    set(umesimd_test_blacklist "")
+
+    if (COMPILER_CLANG)
+        # clang >=4.0.0
+        if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) AND (";${SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD};" MATCHES ";avx512_skx;"))
+            message(AUTHOR_WARNING "Clang >=4.0.0 reevaluate if AVX512_skx (seqan-simd only) binaries are working. "
+                    "At least https://llvm.org/bugs/show_bug.cgi?id=31731 seems to be fixed")
+        # clang =3.9.0
+        elseif (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9) AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9.1)
+            # Build the executables, but don't execute them, because clang <= 3.9.x
+            # produces executables which contain invalid instructions for AVX512.
+            simd_list_version_greater(umesimd_test_blacklist avx2)
+            simd_list_version_greater(seqansimd_test_blacklist avx2)
+            set(reason_for_disabled_test "Clang 3.9.0 produces executables that contain invalid instructions for at least AVX512_knl and AVX512_skx")
+        # clang =3.9.1
+        elseif (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9.1) AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9.2)
+            simd_list_version_greater(seqansimd_test_blacklist avx512_knl)
+            set(reason_for_disabled_test "Clang 3.9.1 produces executables that contain invalid instructions for at least AVX512_skx (seqan-simd only), see https://llvm.org/bugs/show_bug.cgi?id=31731")
+        # clang >=3.9.2
+        elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.9.1 AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0.0)
+            message(AUTHOR_WARNING "Clang >=3.9.2 reevaluate if AVX512_skx (seqan-simd only) binaries are working.")
+        # clang 3.7.x
+        elseif(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.7) AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.8))
+            ## seqan-simd:
+            # avx2: clang 3.7.x fails test cases:
+            #       SimdVectorTestCommon_ShuffleConstant1 type parameter (un-)signed char __vector(32) FAILED
+            #       SimdVectorTestCommon_ShuffleConstant1 type parameter (un-)signed short __vector(16) FAILED
+            simd_list_version_greater(seqansimd_test_blacklist sse4)
+            set(reason_for_disabled_test "Clang 3.7.x produces executables that fail the basic vector test `test_simd_vector`")
+        endif()
+    elseif (COMPILER_LINTEL)
+        # icc >=17.0.0, <=17.0.4
+        if (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0.0) AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0.5)
+            ## seqan-simd:
+            # all: icc 17.0.x fails test cases [test_align_simd_*]:
+            #       SimdAlignTestCommon_Linear_Align type parameter [...] FAILED
+            #       SimdAlignTestCommon_Linear_Score type parameter [...] FAILED
+            if (NOT ("${target}" MATCHES "test_simd_vector"))
+                set(seqansimd_test_blacklist ${SEQAN_SIMD_SUPPORTED_EXTENSIONS})
+                set(reason_for_disabled_test "Intel compiler 17.0.{0-4} produces executables that fail complex tests like `[test_align_simd_*]`")
+            endif()
+        # icc >=17.0.5
+        elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 17.0.4)
+            message(AUTHOR_WARNING "Intel compiler >=17.0.5 reevaluate if [test_align_simd_*] can be compiled.")
+        endif()
+    endif()
+
+    if(COMPILER_GCC AND DEFINED ENV{TRAVIS} AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
+        # Disable avx2,avx512_knl,... on travis, because sometimes gcc 5.x and 6.x crashes
+        simd_list_version_greater(_travis_compile_blacklist sse4)
+        set(seqansimd_compile_blacklist ${seqansimd_compile_blacklist} ${_travis_compile_blacklist})
+        set(umesimd_compile_blacklist ${umesimd_compile_blacklist} ${_travis_compile_blacklist})
+        message(STATUS "Don't compile ${seqansimd_compile_blacklist} on travis, because gcc<=6.x crashes occasionally")
+    endif()
+
+    # detect simd support by try-compile and try-run
+    detect_simd_support()
+
+    # exclude all simd extensions where a simple try-compile failed
+    list_complement(_simd_intrinsics_blacklist "${SEQAN_SIMD_SUPPORTED_EXTENSIONS}" "${SEQAN_SIMD_COMPILER_SUPPORTS_INTRINSICS}")
+    list_complement(_simd_seqansimd_blacklist "${SEQAN_SIMD_SUPPORTED_EXTENSIONS}" "${SEQAN_SIMD_COMPILER_SUPPORTS_SEQANSIMD}")
+    set(seqansimd_compile_blacklist ${seqansimd_compile_blacklist} ${_simd_intrinsics_blacklist} ${_simd_seqansimd_blacklist})
+    set(umesimd_compile_blacklist ${umesimd_compile_blacklist} ${_simd_intrinsics_blacklist})
+
+    if (UMESIMD_FOUND AND umesimd_test_blacklist)
+        message(STATUS "Disable test `${target}` for seqan-simd and ume-simd and the following simd extensions ${seqansimd_test_blacklist} and ${umesimd_test_blacklist}")
+        message(STATUS "\tReason: ${reason_for_disabled_test}")
+    elseif (UMESIMD_FOUND AND umesimd_test_blacklist AND seqansimd_test_blacklist)
+        message(STATUS "Disable test `${target}` for ume-simd and the following simd extensions ${umesimd_test_blacklist}")
+        message(STATUS "\tReason: ${reason_for_disabled_test}")
+    elseif (seqansimd_test_blacklist)
+        message(STATUS "Disable test `${target}` for seqan-simd and the following simd extensions ${seqansimd_test_blacklist}")
+        message(STATUS "\tReason: ${reason_for_disabled_test}")
+    endif()
+
+    if (SEQAN_SIMD_UTILITY_VERBOSE)
+        message(STATUS "seqansimd_compile_blacklist: ${seqansimd_compile_blacklist}")
+        message(STATUS "umesimd_compile_blacklist: ${umesimd_compile_blacklist}")
+        message(STATUS "seqansimd_test_blacklist: ${seqansimd_test_blacklist}")
+        message(STATUS "umesimd_test_blacklist: ${umesimd_test_blacklist}")
+    endif()
+
+    add_simd_executables("${target}" "${seqansimd_compile_blacklist}")
+    add_simd_tests("${target}" "${seqansimd_test_blacklist}")
+
+    if (UMESIMD_FOUND)
+        add_simd_executables("${target}_umesimd" "${umesimd_compile_blacklist}")
+        add_simd_tests("${target}_umesimd" "${umesimd_test_blacklist}")
+    endif()
+endmacro(add_simd_platform_tests)

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



More information about the debian-med-commit mailing list