[med-svn] [seqan2] 01/01: New upstream version 2.4.0~rc0+dfsg

Michael Crusoe misterc-guest at moszumanska.debian.org
Tue Jan 30 10:59:55 UTC 2018


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

misterc-guest pushed a commit to annotated tag upstream/2.4.0_rc0+dfsg
in repository seqan2.

commit 194b7d53498f9fd3194297ab5d96fc12ad913634
Author: Michael R. Crusoe <michael.crusoe at gmail.com>
Date:   Fri Jan 26 09:42:46 2018 -0800

    New upstream version 2.4.0~rc0+dfsg
---
 CHANGELOG.rst                                      |   57 +-
 README.rst                                         |   15 +-
 apps/alf/CMakeLists.txt                            |    2 +-
 apps/alf/alf.cpp                                   |    2 +-
 apps/bs_tools/CMakeLists.txt                       |    2 +-
 apps/bs_tools/casbar_score.h                       |   42 +-
 apps/dfi/CMakeLists.txt                            |    2 +-
 apps/fiona/CMakeLists.txt                          |    2 +-
 apps/fiona/compute_gain.cpp                        |    6 +-
 apps/fx_tools/CMakeLists.txt                       |    2 +-
 apps/gustaf/CMakeLists.txt                         |    2 +-
 apps/insegt/CMakeLists.txt                         |    2 +-
 apps/mason2/CMakeLists.txt                         |    2 +-
 apps/mason2/mason_genome.cpp                       |    2 +-
 apps/mason2/mason_variator.cpp                     |   10 +-
 apps/micro_razers/CMakeLists.txt                   |    2 +-
 apps/ngs_roi/CMakeLists.txt                        |    4 +-
 apps/pair_align/CMakeLists.txt                     |    7 +-
 apps/param_chooser/CMakeLists.txt                  |    2 +-
 apps/rabema/CMakeLists.txt                         |    4 +-
 apps/rabema/rabema_build_gold_standard.cpp         |    2 +-
 apps/rabema/rabema_evaluate.cpp                    |    4 +-
 apps/razers/CMakeLists.txt                         |    7 +-
 apps/razers3/CMakeLists.txt                        |    2 +-
 apps/rep_sep/CMakeLists.txt                        |    2 +-
 apps/sak/CMakeLists.txt                            |    4 +-
 apps/sam2matrix/CMakeLists.txt                     |    2 +-
 apps/samcat/CMakeLists.txt                         |    2 +-
 apps/searchjoin/CMakeLists.txt                     |   16 +-
 apps/searchjoin/db.h                               |    8 +-
 apps/seqan_tcoffee/CMakeLists.txt                  |    2 +-
 apps/seqan_tcoffee/tests/run_tests.py              |    6 +
 apps/seqcons2/CMakeLists.txt                       |    2 +-
 apps/sgip/CMakeLists.txt                           |    2 +-
 apps/snp_store/CMakeLists.txt                      |    2 +-
 apps/splazers/CMakeLists.txt                       |    2 +-
 apps/stellar/CMakeLists.txt                        |    2 +-
 apps/stellar/stellar.cpp                           |    2 +-
 apps/tree_recon/CMakeLists.txt                     |    2 +-
 apps/yara/CMakeLists.txt                           |    2 +-
 apps/yara/find_verifier.h                          |   18 +-
 .../tutorial/file_io_overview/solution3.cpp.stdout |   12 +-
 demos/tutorial/indices/find2_index_approx.cpp      |   57 +
 demos/tutorial/indices/find2_index_approx.stdout   |   23 +
 demos/tutorial/sam_and_bam_io/example7.cpp.stdout  |    6 +-
 dox/CMakeLists.txt                                 |    2 +-
 include/seqan/align.h                              |    2 +
 include/seqan/align/align_interface_wrapper.h      |   52 +-
 .../aligned_sequence_concept.h}                    |   49 +-
 include/seqan/align/dp_algorithm_impl.h            |  725 ++++-----
 include/seqan/align/dp_align_simd_helper.h         |  163 +-
 include/seqan/align/dp_cell.h                      |  110 +-
 include/seqan/align/dp_cell_affine.h               |   35 +-
 include/seqan/align/dp_cell_dynamic.h              |   12 +-
 include/seqan/align/dp_context.h                   |   87 +-
 include/seqan/align/dp_formula.h                   |  251 ++-
 include/seqan/align/dp_formula_affine.h            |  763 +++------
 include/seqan/align/dp_formula_dynamic.h           |  377 +++--
 include/seqan/align/dp_formula_linear.h            |  348 ++--
 include/seqan/align/dp_matrix.h                    |  322 ++--
 include/seqan/align/dp_matrix_navigator.h          |   36 +
 .../seqan/align/dp_matrix_navigator_score_matrix.h |  393 ++---
 .../dp_matrix_navigator_score_matrix_sparse.h      |  351 ++--
 .../seqan/align/dp_matrix_navigator_trace_matrix.h |  377 +++--
 include/seqan/align/dp_matrix_sparse.h             |   38 +-
 include/seqan/align/dp_profile.h                   |  307 ++--
 include/seqan/align/dp_scout.h                     |   24 +-
 include/seqan/align/dp_scout_simd.h                |  332 +++-
 include/seqan/align/dp_setup.h                     |   86 +-
 include/seqan/align/dp_trace_segment.h             |    8 +-
 include/seqan/align/dp_traceback_impl.h            |  161 +-
 include/seqan/align/gaps_anchor.h                  |    2 +-
 include/seqan/align/gaps_base.h                    |    6 +
 include/seqan/align/global_alignment_banded.h      |  118 +-
 include/seqan/align/global_alignment_unbanded.h    |  134 +-
 include/seqan/align/local_alignment_banded.h       |   73 +-
 include/seqan/align/local_alignment_unbanded.h     |  109 +-
 .../align/local_alignment_waterman_eggert_impl.h   |   39 +-
 include/seqan/align/matrix_base.h                  |  333 ++--
 include/seqan/align_extend/align_extend.h          |    4 +-
 include/seqan/align_extend/align_extend_base.h     |   16 +-
 include/seqan/align_extend/dp_scout_xdrop.h        |   19 +-
 .../{parallel/parallel_tags.h => align_parallel.h} |   88 +-
 .../async_wave_execution_interface.h               |  252 +++
 include/seqan/align_parallel/dp_kernel_adaptor.h   |  343 ++++
 .../dp_parallel_execution_policies.h               |  174 ++
 include/seqan/align_parallel/dp_parallel_scout.h   |  263 +++
 .../seqan/align_parallel/dp_parallel_scout_simd.h  |  362 +++++
 .../dp_settings.h}                                 |   95 +-
 .../parallel_tags.h => align_parallel/dp_traits.h} |  106 +-
 .../align_parallel/parallel_align_interface.h      |  366 +++++
 .../wavefront_alignment_executor.h}                |   76 +-
 .../align_parallel/wavefront_alignment_result.h    |  165 ++
 .../align_parallel/wavefront_alignment_scheduler.h |  347 ++++
 .../align_parallel/wavefront_alignment_task.h      |  404 +++++
 .../wavefront_alignment_thread_local_storage.h     |  130 ++
 include/seqan/align_parallel/wavefront_task.h      |  365 +++++
 .../wavefront_task_event.h}                        |   82 +-
 .../seqan/align_parallel/wavefront_task_executor.h |  146 ++
 .../wavefront_task_queue.h}                        |  121 +-
 .../align_parallel/wavefront_task_scheduler.h      |  218 +++
 include/seqan/align_parallel/wavefront_task_util.h |  557 +++++++
 include/seqan/align_split/align_split_interface.h  |   51 +-
 include/seqan/arg_parse/arg_parse_argument.h       |   36 +-
 include/seqan/arg_parse/tool_doc.h                 |    7 +
 include/seqan/bam_io/bam_alignment_record_util.h   |    2 +-
 include/seqan/bam_io/bam_index_bai.h               |   66 +-
 include/seqan/bam_io/read_bam.h                    |    2 +-
 include/seqan/basic/basic_exception.h              |    2 +-
 include/seqan/basic/fundamental_metafunctions.h    |   20 +-
 include/seqan/basic/fundamental_tags.h             |    2 +-
 include/seqan/basic/iterator_range.h               |   30 +-
 include/seqan/basic/pair_packed.h                  |   21 +-
 include/seqan/basic/profiling.h                    |   42 +-
 include/seqan/bed_io/bed_record.h                  |    4 +-
 include/seqan/find/find_myers_ukkonen.h            |   20 +-
 include/seqan/find/find_score.h                    |   15 +-
 include/seqan/index.h                              |    1 +
 include/seqan/index/find2_backtracking.h           |    4 +-
 include/seqan/index/find2_index_approx.h           |  642 ++++++++
 include/seqan/index/find_index_lambda.h            |    4 +-
 include/seqan/index/find_index_qgram.h             |    2 +-
 include/seqan/index/index_base.h                   |    2 +-
 include/seqan/index/index_esa_stree.h              |    4 +-
 include/seqan/index/index_fm_compressed_sa.h       |    6 +-
 include/seqan/index/index_fm_lf_table.h            |   59 +-
 .../seqan/index/index_fm_rank_dictionary_base.h    |   88 +-
 .../seqan/index/index_fm_rank_dictionary_levels.h  |    6 +-
 .../seqan/index/index_fm_rank_dictionary_naive.h   |    2 +-
 include/seqan/index/index_fm_rank_dictionary_wt.h  |   55 +
 include/seqan/index/index_qgram.h                  |    2 +-
 include/seqan/journaled_string_tree/delta_map.h    |    2 +-
 .../journaled_string_tree_impl.h                   |    2 +-
 .../journaled_string_tree_traverser_util.h         |    2 +-
 include/seqan/modifier/modifier_padding.h          |   53 +-
 include/seqan/parallel.h                           |    6 +
 include/seqan/parallel/enumerable_thread_local.h   |  476 ++++++
 .../parallel/enumerable_thread_local_iterator.h    |  186 +++
 include/seqan/parallel/parallel_algorithms.h       |    7 +-
 include/seqan/parallel/parallel_queue.h            |   24 +-
 .../seqan/parallel/parallel_queue_suspendable.h    |   16 +-
 include/seqan/parallel/parallel_tags.h             |  172 ++
 include/seqan/parallel/parallel_thread_pool.h      |  219 +++
 include/seqan/pipe/pipe_sampler.h                  |    2 +-
 include/seqan/platform.h                           |   30 +-
 include/seqan/score/score_matrix.h                 |    8 +
 include/seqan/score/score_matrix_data.h            |   72 +-
 include/seqan/score/score_matrix_dyn.h             |   19 +
 include/seqan/score/score_simd_wrapper.h           |   36 +-
 include/seqan/seeds/banded_chain_alignment_impl.h  |  294 ++--
 .../seqan/seeds/banded_chain_alignment_profile.h   |   24 +-
 .../seqan/seeds/banded_chain_alignment_traceback.h |   34 +-
 include/seqan/seeds/seeds_global_chaining.h        |  162 +-
 include/seqan/sequence/string_alloc.h              |   22 +-
 include/seqan/sequence/string_base.h               |   24 +
 include/seqan/sequence/string_set_concat_direct.h  |    6 +-
 include/seqan/sequence/string_set_owner.h          |    4 +-
 include/seqan/simd.h                               |   19 +-
 include/seqan/simd/simd_base.h                     |   99 +-
 include/seqan/simd/simd_base_seqan_impl.h          |   15 +-
 include/seqan/simd/simd_base_seqan_impl_avx2.h     |   11 -
 include/seqan/simd/simd_base_seqan_impl_avx512.h   |  284 ++++
 include/seqan/simd/simd_base_seqan_impl_sse4.2.h   |    8 +-
 include/seqan/simd/simd_base_seqan_interface.h     |   33 +-
 include/seqan/simd/simd_base_umesimd_impl.h        |   90 +-
 include/seqan/store/store_all.h                    |    4 +-
 include/seqan/store/store_io_sam.h                 |    2 +-
 include/seqan/stream/file_stream.h                 |    8 +-
 include/seqan/stream/iter_stream.h                 |  184 ++-
 include/seqan/stream/virtual_stream.h              |   13 +-
 include/seqan/translation/translation.h            |   12 +-
 include/seqan/vcf_io/read_vcf.h                    |  126 +-
 manual/source/Infrastructure/Use/Install.rst       |   42 +-
 .../PatternMatching/OptimalSearchSchemes.rst       |   72 +
 .../Tutorial/Algorithms/PatternMatching/index.rst  |    2 +
 .../Tutorial/GettingStarted/AFirstExample.rst      |    1 +
 .../GettingStarted/BackgroundAndMotivation.rst     |    4 +-
 tests/align/CMakeLists.txt                         |   46 +-
 tests/align/test_align.cpp                         |   14 +-
 tests/align/test_align_simd.h                      |  559 -------
 tests/align/test_align_simd_base.h                 |  265 +++
 tests/align/test_align_simd_global.h               |  122 ++
 ...cpp => test_align_simd_global_equal_length.cpp} |   26 +-
 ... => test_align_simd_global_variable_length.cpp} |   21 +-
 tests/align/test_align_simd_local.h                |  122 ++
 ....cpp => test_align_simd_local_equal_length.cpp} |   19 +-
 ...p => test_align_simd_local_variable_length.cpp} |   18 +-
 .../test_alignment_algorithms_band_position.h      |   62 +-
 tests/align/test_alignment_algorithms_local.h      |   47 +
 .../align/test_alignment_algorithms_local_banded.h |   32 +
 .../align/test_alignment_dp_adapt_tracesegments.h  |   80 +-
 tests/align/test_alignment_dp_formula.h            | 1326 +++++++++------
 tests/align/test_alignment_dp_matrix.h             |    2 +-
 tests/align/test_alignment_dp_matrix_navigator.h   | 1704 ++++----------------
 tests/align/test_alignment_dp_trace_segment.h      |   52 +-
 tests/align/test_alignment_dp_traceback.h          |  395 +++--
 tests/align/test_mock.h                            |  240 +++
 tests/align_parallel/CMakeLists.txt                |   78 +
 .../test_align_parallel_algorithm.cpp}             |   20 +-
 .../test_align_parallel_data_structures.cpp}       |   83 +-
 .../test_align_parallel_interface.cpp}             |    2 +-
 .../align_parallel/test_align_parallel_interface.h |  168 ++
 .../test_align_parallel_wavefront_alignment.h      |  183 +++
 .../test_align_wavefront_alignment_scheduler.h     |  267 +++
 .../test_align_wavefront_alignment_thread_local.h  |   93 +-
 .../test_align_wavefront_intermediate_dp_result.h  |  121 ++
 .../test_align_wavefront_task_scheduler.h}         |  111 +-
 tests/arg_parse/test_arg_parse.cpp                 |    1 +
 tests/arg_parse/test_arg_parse_argument.h          |   28 +
 tests/basic/test_basic_aggregate.h                 |    5 +-
 tests/index/CMakeLists.txt                         |    6 +-
 .../test_find2_index_approx.cpp}                   |   21 +-
 tests/index/test_find2_index_approx.h              |  489 ++++++
 tests/index/test_index_bifm.cpp                    |   14 +-
 tests/modifier/test_modifier.cpp                   |    3 +-
 tests/modifier/test_modifier_string_padding.h      |   24 +
 .../test_multiple_translation_units.cpp            |    1 +
 .../test_multiple_translation_units_2.cpp          |    1 +
 tests/parallel/CMakeLists.txt                      |    4 +-
 tests/parallel/test_parallel.cpp                   |   21 +
 .../test_parallel_enumerable_thread_local.h        |  217 +++
 tests/parallel/test_parallel_thread_pool.h         |  151 ++
 tests/seeds/test_seeds_global_chaining.cpp         |   26 +
 tests/simd/test_simd_vector.h                      |    9 +-
 tests/translation/test_translation.h               |   36 +
 tests/vcf_io/example_records_with_errors.vcf       |    5 +-
 tests/vcf_io/test_vcf_io.h                         |   30 +-
 util/cmake/SeqAnBuildSystem.cmake                  |   33 +-
 util/cmake/SeqAnSimdUtility.cmake                  |   42 +-
 util/cmake/seqan-config.cmake                      |   17 +-
 util/pkgconfig/seqan.pc.in                         |    4 +-
 util/skel/app_template/CMakeLists.txt              |    2 +-
 util/travis/linux-cibuild.cmake                    |    1 -
 util/travis/linux-cibuild.sh                       |    5 +
 234 files changed, 15786 insertions(+), 7098 deletions(-)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 6c2dfcf..ea0d6f4 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -3,6 +3,59 @@ SeqAn Changelog
 
 This file summarizes the changes to the SeqAn library and apps.
 
+Release 2.4.0
+~~~~~~~~~~~~~
+
+Library Features
+^^^^^^^^^^^^^^^^
+
+- Align
+   - Generic parallelisation and vectorisation.
+   - Support for SSE4, AVX2 and AVX512.
+   - Speed-Ups of > 1000x compared to serial execution of long DNA alignments.
+- Indexing
+   - Parallel ``find()`` interface
+   - Support for optimal search schemes (https://arxiv.org/abs/1711.02035)
+- ReducedAminoAcid
+   - several new Reduced Amino Acid alphabets are now available.
+- VCF I/O
+   - Now supports version 4.2 of the specification, i.e. columns with only eight fields.
+
+Selected Bug Fixes
+^^^^^^^^^^^^^^^^^^
+
+- BAM I/O
+   - Fix of jumpToRegion() functionality to start at the desired region instead of the index block.
+   - Works correctly on big endian platforms now.
+- Translation
+   - Handle empty/too-short input correctly.
+- Code Cleanup
+   - various parts of the codebase have undergone cleanup and may now report deprecated functionality as being deprecated via compiler-functionality.
+
+Platform Support
+^^^^^^^^^^^^^^^^
+
+- Compiler support:
+   - Satisfies stricter warning levels of GCC-8, Clang-5 also with ``-std=c++17``.
+   - Supports VS2017.
+   - Intel Compiler suite 2016 **was dropped**.
+   - Intel Compiler suites 2017 and 2018 are newly supported.
+   - GCC-4.9 on MacOS **was dropped** (newer GCC available everywhere via MacPorts or Homebrew).
+   - Clang-3.5 on FreeBSD **was dropped** (newer Clang available in base system and Ports).
+- CPU architectures support:
+   - Substantial fixes for big endian platforms
+   - Now officially supported and passing integration tests:
+      - ``i386, amd64/intel64, x32, ia64``
+      - ``armel, armhf, arm64``
+      - ``mips, mipsel, mips64el``
+      - ``powerpc, ppc64, ppc64el``
+      - ``s390x, alpha, m68k, sh4``
+   - Officially **not** supported: ``sparc64``
+   - Thanks to the Debian Med team for their patches!
+- Upstream packages:
+   - SeqAn2 packages are finally coming to Fedora, thanks to @sagitter
+   - Package updates in Debian, Ubuntu, MacPorts, Homebrew and FreeBSD expected shortly.
+
 Release 2.3.2
 ~~~~~~~~~~~~~
 
@@ -16,8 +69,8 @@ Selected Bug Fixes
    - reintroduce ``FindSeqAn.cmake`` for projects that rely on cmake's module mode
    - fix the pkgconfig file
 - Platform related
-   - improved compliance with warning levels of soon-to-be-released gcc7 and clang4 
-   - because of unresolved bugs we now recommend gcc5 as minimum gcc version when using static linking 
+   - improved compliance with warning levels of soon-to-be-released gcc7 and clang4
+   - because of unresolved bugs we now recommend gcc5 as minimum gcc version when using static linking
 
 Release 2.3.1
 ~~~~~~~~~~~~~
diff --git a/README.rst b/README.rst
index 8b9c357..1043974 100644
--- a/README.rst
+++ b/README.rst
@@ -21,19 +21,18 @@ The licenses for the applications themselves can be found in the LICENSE files.
 Prerequisites
 -------------------
 
-Linux, Mac OSX, FreeBSD:
-  * GCC ≥ 4.9 [GCC ≥ 5 recommended]
-  * Clang/LLVM ≥ 3.5
-  * Intel Compiler ≥ 16.0.2
+Linux, MacOS, FreeBSD:
+  * GCC ≥ 5 [limited GCC-4.9 support on Linux]
+  * Clang/LLVM ≥ 3.6 [limited Clang-3.5 support on Linux]
+  * Intel Compiler ≥ 17.0.0 on Linux
 Windows:
   * Visual C++ ≥ 14.0 / Visual Studio ≥ 2015
-  * Intel Compiler ≥ 16.0.3 / Visual Studio ≥ 2015u2
+  * Intel Compiler ≥ 17.0.0 / Visual Studio ≥ 2015u2
   * Clang/C2 ≥ 3.8.0 / Visual Studio ≥ 2015u3 [experimental, requires CMake ≥ 3.6]
 
 Architecture support:
-  * 32bit and 64bit Intel/AMD officially supported
-  * 64bit is highly recommended and some parts of SeqAn are optimized for ``POPCNT``, ``SSE4`` and/or ``AVX2`` instruction sets available on newer CPUs
-  * many other architectures, including ARM, PowerPC and Sparc64 work, but receive less testing and optimizations
+  * Intel/AMD platforms, including optimisations for modern instruction sets (``POPCNT``, ``SSE4``, ``AVX2``, ``AVX512``)
+  * All Debian release architectures supported, including most ARM and all PowerPC platforms.
 
 To build tests, demos, and official SeqAn applications you also need:
   * CMake ≥ 3.0 [CMake ≥ 3.4 recommended]
diff --git a/apps/alf/CMakeLists.txt b/apps/alf/CMakeLists.txt
index e198d89..20b98cd 100644
--- a/apps/alf/CMakeLists.txt
+++ b/apps/alf/CMakeLists.txt
@@ -56,7 +56,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install alf in ${PREFIX}/bin directory
 install (TARGETS alf
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/alf for SeqAn release builds.
diff --git a/apps/alf/alf.cpp b/apps/alf/alf.cpp
index 813a377..b4b45d8 100644
--- a/apps/alf/alf.cpp
+++ b/apps/alf/alf.cpp
@@ -74,7 +74,7 @@ int main(int argc, const char * argv[])
     // Options Section: Input / Output parameters.
     addSection(parser, "Input / Output");
     addOption(parser, seqan::ArgParseOption("i", "input-file", "Name of the multi-FASTA input file.", seqan::ArgParseArgument::INPUT_FILE));
-    setValidValues(parser, "input-file", "fa fasta");
+    setValidValues(parser, "input-file", seqan::SeqFileIn::getFileExtensions());
     setRequired(parser, "input-file");
     addOption(parser, seqan::ArgParseOption("o", "output-file", "Name of the file to which the tab-delimtied matrix with pairwise scores will be written to.  Default is to write to stdout.", seqan::ArgParseArgument::OUTPUT_FILE));
     setValidValues(parser, "output-file", "alf.tsv");
diff --git a/apps/bs_tools/CMakeLists.txt b/apps/bs_tools/CMakeLists.txt
index 8732293..ebe3ab8 100644
--- a/apps/bs_tools/CMakeLists.txt
+++ b/apps/bs_tools/CMakeLists.txt
@@ -99,7 +99,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install bs_tools in ${PREFIX}/bin directory
 install (TARGETS bisar casbar four2three
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/bs_tools for SeqAn release builds.
diff --git a/apps/bs_tools/casbar_score.h b/apps/bs_tools/casbar_score.h
index 50ece61..ea9cc6b 100644
--- a/apps/bs_tools/casbar_score.h
+++ b/apps/bs_tools/casbar_score.h
@@ -363,16 +363,20 @@ sequenceEntryForScore(Score<TScoreValue, BsTagList<TBsProfileScore, TModel, TCel
 // Modify to use different scoring function at first and last row
 // (end gaps score different)
 // Computes the score and tracks it if enabled.
-template <typename TDPScout, typename TTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
-          typename TSequenceHValue, typename TSequenceVValue, typename TBsProfileScore, typename TModel, typename TCellDescriptor2, typename TColumnDescriptor,
+template <typename TDPScout, typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoreValue, typename TBsProfileScore, typename TModel, typename TCellDescriptor2,
+          typename TColumnDescriptor,
           typename TDPProfile>
 inline void
 _computeCell(TDPScout & scout,
              TTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const & previousDiagonal,
-             DPCell_<TScoreValue, TGapCosts> const & previousHorizontal,
-             DPCell_<TScoreValue, TGapCosts> const & previousVertical,
+             TDPCell & c,
+             TDPCell & d,
+             TDPCell const & h,
+             TDPCell & v,
              TSequenceHValue const & seqHVal,
              TSequenceVValue const & seqVVal,
              Score<TScoreValue, BsTagList<TBsProfileScore, TModel, TCellDescriptor2> > const & scoringScheme,
@@ -385,7 +389,7 @@ _computeCell(TDPScout & scout,
 
     Score<TScoreValue, BsTagList<TBsProfileScore, TModel, FirstCell> > scoringSchemeDummy(scoringScheme);
     assignValue(traceMatrixNavigator,
-                _computeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal, seqVVal,
+                _computeScore(c, d, h, v, seqHVal, seqVVal,
                               scoringSchemeDummy, typename RecursionDirection_<TMetaColumn, TCellDescriptor>::Type(),
                               TDPProfile()));
 //	std::cout << "("<< activeCell._score << "," << previousDiagonal._score << "," << previousHorizontal._score << "," << previousVertical._score << ") ";
@@ -395,23 +399,28 @@ _computeCell(TDPScout & scout,
         bool isLastRow = And<IsSameType<TCellDescriptor, LastCell>,
                              Or<IsSameType<typename TColumnDescriptor::TLocation, PartialColumnBottom>,
                                 IsSameType<typename TColumnDescriptor::TLocation, FullColumn> > >::VALUE;
-        _scoutBestScore(scout, activeCell, traceMatrixNavigator, isLastColumn, isLastRow);
+        _setVerticalScoreOfCell(c, _verticalScoreOfCell(v));
+        _scoutBestScore(scout, c, traceMatrixNavigator, isLastColumn, isLastRow);
     }
 }
 
 // Modify to use different scoring function at first and last row
 // (end gaps score different)
 // Computes the score and tracks it if enabled.
-template <typename TDPScout, typename TTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
-          typename TSequenceHValue, typename TSequenceVValue, typename TBsProfileScore, typename TModel, typename TCellDescriptor2, typename TColumnDescriptor,
+template <typename TDPScout, typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoreValue, typename TBsProfileScore, typename TModel, typename TCellDescriptor2,
+          typename TColumnDescriptor,
           typename TDPProfile>
 inline void
 _computeCell(TDPScout & scout,
              TTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const & previousDiagonal,
-             DPCell_<TScoreValue, TGapCosts> const & previousHorizontal,
-             DPCell_<TScoreValue, TGapCosts> const & previousVertical,
+             TDPCell & c,
+             TDPCell & d,
+             TDPCell const & h,
+             TDPCell & v,
              TSequenceHValue const & seqHVal,
              TSequenceVValue const & seqVVal,
              Score<TScoreValue, BsTagList<TBsProfileScore, TModel, TCellDescriptor2> > const & scoringScheme,
@@ -424,7 +433,7 @@ _computeCell(TDPScout & scout,
 
     Score<TScoreValue, BsTagList<TBsProfileScore, TModel, LastCell> > scoringSchemeDummy(scoringScheme);
     assignValue(traceMatrixNavigator,
-                _computeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal, seqVVal,
+                _computeScore(c, d, h, v, seqHVal, seqVVal,
                               scoringSchemeDummy, typename RecursionDirection_<TMetaColumn, TCellDescriptor>::Type(),
                               TDPProfile()));
 //	std::cout << "("<< activeCell._score << "," << previousDiagonal._score << "," << previousHorizontal._score << "," << previousVertical._score << ") ";
@@ -434,7 +443,8 @@ _computeCell(TDPScout & scout,
         bool isLastRow = And<IsSameType<TCellDescriptor, LastCell>,
                              Or<IsSameType<typename TColumnDescriptor::TLocation, PartialColumnBottom>,
                                 IsSameType<typename TColumnDescriptor::TLocation, FullColumn> > >::VALUE;
-        _scoutBestScore(scout, activeCell, traceMatrixNavigator, isLastColumn, isLastRow);
+        _setVerticalScoreOfCell(c, _verticalScoreOfCell(v));
+        _scoutBestScore(scout, c, traceMatrixNavigator, isLastColumn, isLastRow);
     }
 }
 
diff --git a/apps/dfi/CMakeLists.txt b/apps/dfi/CMakeLists.txt
index ee9e7c6..1b9274a 100644
--- a/apps/dfi/CMakeLists.txt
+++ b/apps/dfi/CMakeLists.txt
@@ -56,7 +56,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install dfi in ${PREFIX}/bin directory
 install (TARGETS dfi
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/dfi for SeqAn release builds.
diff --git a/apps/fiona/CMakeLists.txt b/apps/fiona/CMakeLists.txt
index babd267..9e68130 100644
--- a/apps/fiona/CMakeLists.txt
+++ b/apps/fiona/CMakeLists.txt
@@ -83,7 +83,7 @@ if (NOT SEQAN_PREFIX_SHARE_DOC)
 endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install fiona in ${PREFIX}/bin directory
-install (TARGETS fiona compute_gain DESTINATION bin)
+install (TARGETS fiona compute_gain DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/fiona for SeqAn release builds.
diff --git a/apps/fiona/compute_gain.cpp b/apps/fiona/compute_gain.cpp
index 523daa5..26876a8 100644
--- a/apps/fiona/compute_gain.cpp
+++ b/apps/fiona/compute_gain.cpp
@@ -798,7 +798,7 @@ parseCommandLine(Options & options, int argc, char const ** argv)
     addOption(parser, seqan::ArgParseOption("g", "genome", "Genome file.", seqan::ArgParseOption::INPUT_FILE,
                                             "GENOME.fa"));
     setRequired(parser, "genome");
-    setValidValues(parser, "genome", "fa fasta");
+    setValidValues(parser, "genome", seqan::SeqFileIn::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("", "pre", "Pre-correction SAM file.", seqan::ArgParseOption::INPUT_FILE,
                                             "PRE.{sam,bam}"));
@@ -1028,10 +1028,10 @@ int main(int argc, char const ** argv)
                     stop = atEnd(inPostBam);
                 else
                     stop = atEnd(inPostFastq);
-                
+
                 if (stop)
                     break;
-                
+
                 // Read next record into chunk.
                 try
                 {
diff --git a/apps/fx_tools/CMakeLists.txt b/apps/fx_tools/CMakeLists.txt
index b0e9d7e..09a265d 100644
--- a/apps/fx_tools/CMakeLists.txt
+++ b/apps/fx_tools/CMakeLists.txt
@@ -55,7 +55,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install fx_tools in ${PREFIX}/bin directory
 install (TARGETS fx_bam_coverage
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/fx_tools for SeqAn release builds.
diff --git a/apps/gustaf/CMakeLists.txt b/apps/gustaf/CMakeLists.txt
index d8ae684..a1b28ca 100644
--- a/apps/gustaf/CMakeLists.txt
+++ b/apps/gustaf/CMakeLists.txt
@@ -77,7 +77,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install gustaf in ${PREFIX}/bin directory
 install (TARGETS gustaf gustaf_mate_joining
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/gustaf for SeqAn release builds.
diff --git a/apps/insegt/CMakeLists.txt b/apps/insegt/CMakeLists.txt
index 6adda64..d78484a 100644
--- a/apps/insegt/CMakeLists.txt
+++ b/apps/insegt/CMakeLists.txt
@@ -61,7 +61,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install insegt in ${PREFIX}/bin directory
 install (TARGETS insegt
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/insegt for SeqAn release builds.
diff --git a/apps/mason2/CMakeLists.txt b/apps/mason2/CMakeLists.txt
index eaf4345..57dc904 100644
--- a/apps/mason2/CMakeLists.txt
+++ b/apps/mason2/CMakeLists.txt
@@ -143,7 +143,7 @@ install (TARGETS mason_frag_sequencing
                  mason_simulator
                  mason_splicing
                  mason_variator
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/mason2 for SeqAn release builds.
diff --git a/apps/mason2/mason_genome.cpp b/apps/mason2/mason_genome.cpp
index 76383cc..a41cf4d 100644
--- a/apps/mason2/mason_genome.cpp
+++ b/apps/mason2/mason_genome.cpp
@@ -115,7 +115,7 @@ parseCommandLine(MasonGenomeOptions & options, int argc, char const ** argv)
     addSection(parser, "Output Options");
     addOption(parser, seqan::ArgParseOption("o", "out-file", "Output file.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "FILE"));
-    setValidValues(parser, "out-file", "fa fasta");
+    setValidValues(parser, "out-file", seqan::SeqFileOut::getFileExtensions());
     setRequired(parser, "out-file");
 
     // Add Examples Section.
diff --git a/apps/mason2/mason_variator.cpp b/apps/mason2/mason_variator.cpp
index cc27c96..e75ffc2 100644
--- a/apps/mason2/mason_variator.cpp
+++ b/apps/mason2/mason_variator.cpp
@@ -710,7 +710,7 @@ public:
     {
         if (isNearN(seq, pos))
             return false;  // No SNP next to an N.
-        
+
         // We simulate an alternative base for each haplotype.
 
         seqan::Dna5 from = seq[pos];
@@ -1575,7 +1575,7 @@ public:
 
         vcfRecord.rID = svRecord.rId;
         vcfRecord.beginPos = svRecord.pos - 1;
-        vcfRecord.id = variants.getVariantName(variants.posToIdx(Variants::SV, svIdx)); 
+        vcfRecord.id = variants.getVariantName(variants.posToIdx(Variants::SV, svIdx));
         appendValue(vcfRecord.ref, contig[vcfRecord.beginPos]);
         vcfRecord.alt = "<INV>";
         vcfRecord.filter = "PASS";
@@ -1613,7 +1613,7 @@ public:
         seqan::VcfRecord vcfRecord;
         vcfRecord.rID = svRecord.rId;
         vcfRecord.beginPos = svRecord.pos - 1;
-        vcfRecord.id = variants.getVariantName(variants.posToIdx(Variants::SV, svIdx)); 
+        vcfRecord.id = variants.getVariantName(variants.posToIdx(Variants::SV, svIdx));
         vcfRecord.filter = "PASS";
         std::stringstream ss;
         ss << "SVTYPE=DUP;SVLEN=" << svRecord.size << ";END=" << svRecord.pos + svRecord.size
@@ -1814,12 +1814,12 @@ parseCommandLine(MasonVariatorOptions & options, int argc, char const ** argv)
     addOption(parser, seqan::ArgParseOption("", "meth-fasta-in", "Path to load original methylation levels from.  "
                                             "Methylation levels are simulated if omitted.",
                                             seqan::ArgParseOption::INPUT_FILE, "FILE"));
-    setValidValues(parser, "meth-fasta-in", "fa fasta");
+    setValidValues(parser, "meth-fasta-in", seqan::SeqFileIn::getFileExtensions());
 
     addOption(parser, seqan::ArgParseOption("", "meth-fasta-out", "Path to write methylation levels to as FASTA.  "
                                             "Only written if \\fB-of\\fP/\\fB--out-fasta\\fP is given.",
                                             seqan::ArgParseOption::OUTPUT_FILE, "FILE"));
-    setValidValues(parser, "meth-fasta-out", "fa fasta");
+    setValidValues(parser, "meth-fasta-out", seqan::SeqFileOut::getFileExtensions());
 
 
     // ----------------------------------------------------------------------
diff --git a/apps/micro_razers/CMakeLists.txt b/apps/micro_razers/CMakeLists.txt
index 5e2dd4f..4449ac4 100644
--- a/apps/micro_razers/CMakeLists.txt
+++ b/apps/micro_razers/CMakeLists.txt
@@ -62,7 +62,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install micro_razers in ${PREFIX}/bin directory
 install (TARGETS micro_razers
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/micro_razers for SeqAn release builds.
diff --git a/apps/ngs_roi/CMakeLists.txt b/apps/ngs_roi/CMakeLists.txt
index 2ee38bd..3633699 100644
--- a/apps/ngs_roi/CMakeLists.txt
+++ b/apps/ngs_roi/CMakeLists.txt
@@ -77,7 +77,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 install (TARGETS bam2roi
                  roi_feature_projection
                  roi_plot_thumbnails
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install helper scripts into ${PREFIX}/bin directory.
 install (FILES # Scripts for sorting.
@@ -88,7 +88,7 @@ install (FILES # Scripts for sorting.
                  tool_shed/roi_plot_9.sh
                  tool_shed/plot.awk
                  tool_shed/ps2pswLinks.gawk
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/ngs_roi for SeqAn release builds.
diff --git a/apps/pair_align/CMakeLists.txt b/apps/pair_align/CMakeLists.txt
index 70f9e5c..dd2733a 100644
--- a/apps/pair_align/CMakeLists.txt
+++ b/apps/pair_align/CMakeLists.txt
@@ -12,6 +12,11 @@ message (STATUS "Configuring apps/pair_align")
 
 set (SEQAN_APP_VERSION "1.3.7")
 
+if (SEQAN_TRAVIS_BUILD)
+    message (STATUS "  Skipping build and test of pair_align on Travis CI.")
+    return ()
+endif (SEQAN_TRAVIS_BUILD)
+
 # ----------------------------------------------------------------------------
 # Dependencies
 # ----------------------------------------------------------------------------
@@ -60,7 +65,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install pair_align in ${PREFIX}/bin directory
 install (TARGETS pair_align
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/pair_align for SeqAn release builds.
diff --git a/apps/param_chooser/CMakeLists.txt b/apps/param_chooser/CMakeLists.txt
index ef4cfeb..005ec4c 100644
--- a/apps/param_chooser/CMakeLists.txt
+++ b/apps/param_chooser/CMakeLists.txt
@@ -62,7 +62,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install param_chooser in ${PREFIX}/bin directory
 install (TARGETS param_chooser
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/param_chooser for SeqAn release builds.
diff --git a/apps/rabema/CMakeLists.txt b/apps/rabema/CMakeLists.txt
index 723e225..96d322a 100644
--- a/apps/rabema/CMakeLists.txt
+++ b/apps/rabema/CMakeLists.txt
@@ -91,11 +91,11 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 install (TARGETS rabema_prepare_sam
                  rabema_build_gold_standard
                  rabema_evaluate
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install rabema in /bin directory
 install (TARGETS rabema_prepare_sam rabema_build_gold_standard rabema_evaluate
-        DESTINATION bin)
+        DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/pair_align for SeqAn release builds.
diff --git a/apps/rabema/rabema_build_gold_standard.cpp b/apps/rabema/rabema_build_gold_standard.cpp
index 08ac1fa..1edbe30 100644
--- a/apps/rabema/rabema_build_gold_standard.cpp
+++ b/apps/rabema/rabema_build_gold_standard.cpp
@@ -1003,7 +1003,7 @@ parseCommandLine(BuildGoldStandardOptions & options, int argc, char const ** arg
     addOption(parser, seqan::ArgParseOption("r", "reference", "Path to load reference FASTA from.",
                                             seqan::ArgParseArgument::INPUT_FILE, "FASTA"));
     setRequired(parser, "reference", true);
-    setValidValues(parser, "reference", "fa fasta");
+    setValidValues(parser, "reference", seqan::SeqFileIn::getFileExtensions());
     addOption(parser, seqan::ArgParseOption("b", "in-bam", "Path to load the \"perfect\" SAM/BAM file from.",
                                             seqan::ArgParseArgument::INPUT_FILE, "BAM"));
     setValidValues(parser, "in-bam", BamFileIn::getFileExtensions());
diff --git a/apps/rabema/rabema_evaluate.cpp b/apps/rabema/rabema_evaluate.cpp
index 89c2707..67b3bf9 100644
--- a/apps/rabema/rabema_evaluate.cpp
+++ b/apps/rabema/rabema_evaluate.cpp
@@ -1064,7 +1064,7 @@ parseCommandLine(RabemaEvaluationOptions & options, int argc, char const ** argv
     // setRequired(parser, "out-gsi", true);
     addOption(parser, seqan::ArgParseOption("r", "reference", "Path to load reference FASTA from.",
                                             seqan::ArgParseArgument::INPUT_FILE, "FASTA"));
-    setValidValues(parser, "reference", "fa fasta");
+    setValidValues(parser, "reference", seqan::SeqFileIn::getFileExtensions());
     setRequired(parser, "reference", true);
     addOption(parser, seqan::ArgParseOption("g", "in-gsi",
                                             "Path to load gold standard intervals from. If compressed using gzip, "
@@ -1229,7 +1229,7 @@ parseCommandLine(RabemaEvaluationOptions & options, int argc, char const ** argv
 
     getOptionValue(options.checkSorting, parser, "dont-check-sorting");
     options.checkSorting = !options.checkSorting;
-    
+
     options.showMissedIntervals = isSet(parser, "show-missed-intervals");
     options.showSuperflousIntervals = isSet(parser, "show-invalid-hits");
     options.showAdditionalIntervals = isSet(parser, "show-additional-hits");
diff --git a/apps/razers/CMakeLists.txt b/apps/razers/CMakeLists.txt
index be52d54..14a1098 100644
--- a/apps/razers/CMakeLists.txt
+++ b/apps/razers/CMakeLists.txt
@@ -12,6 +12,11 @@ message (STATUS "Configuring apps/razers")
 
 set (SEQAN_APP_VERSION "1.5.7")
 
+if (SEQAN_TRAVIS_BUILD)
+    message (STATUS "  Skipping build and test of razers on Travis CI.")
+    return ()
+endif (SEQAN_TRAVIS_BUILD)
+
 # ----------------------------------------------------------------------------
 # Dependencies
 # ----------------------------------------------------------------------------
@@ -66,7 +71,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install razers in ${PREFIX}/bin directory
 install (TARGETS razers
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/razers for SeqAn release builds.
diff --git a/apps/razers3/CMakeLists.txt b/apps/razers3/CMakeLists.txt
index 0eb5157..9ec8468 100644
--- a/apps/razers3/CMakeLists.txt
+++ b/apps/razers3/CMakeLists.txt
@@ -92,7 +92,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install razers3 in ${PREFIX}/bin directory
 install (TARGETS razers3
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/razers3 for SeqAn release builds.
diff --git a/apps/rep_sep/CMakeLists.txt b/apps/rep_sep/CMakeLists.txt
index c8b6312..2e11fe6 100644
--- a/apps/rep_sep/CMakeLists.txt
+++ b/apps/rep_sep/CMakeLists.txt
@@ -64,7 +64,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install rep_sep in ${PREFIX}/bin directory
 install (TARGETS rep_sep
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/rep_sep for SeqAn release builds.
diff --git a/apps/sak/CMakeLists.txt b/apps/sak/CMakeLists.txt
index 3687181..c5e9f5b 100644
--- a/apps/sak/CMakeLists.txt
+++ b/apps/sak/CMakeLists.txt
@@ -68,7 +68,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install sak in ${PREFIX}/bin directory
 install (TARGETS sak
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/sak for SeqAn release builds.
@@ -77,7 +77,7 @@ install (FILES LICENSE
                ${CMAKE_CURRENT_BINARY_DIR}/README.sak.txt
          DESTINATION ${SEQAN_PREFIX_SHARE_DOC})
 install (FILES ${CMAKE_CURRENT_BINARY_DIR}/sak.1
-         DESTINATION ${SEQAN_PREFIX_SHARE_DOC}/man)
+         DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
 
 # ----------------------------------------------------------------------------
 # App Test
diff --git a/apps/sam2matrix/CMakeLists.txt b/apps/sam2matrix/CMakeLists.txt
index e0d60ad..3ea10b4 100644
--- a/apps/sam2matrix/CMakeLists.txt
+++ b/apps/sam2matrix/CMakeLists.txt
@@ -56,7 +56,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install sam2matrix in ${PREFIX}/bin directory
 install (TARGETS sam2matrix
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/sam2matrix for SeqAn release builds.
diff --git a/apps/samcat/CMakeLists.txt b/apps/samcat/CMakeLists.txt
index 1fada83..7c1664a 100644
--- a/apps/samcat/CMakeLists.txt
+++ b/apps/samcat/CMakeLists.txt
@@ -63,7 +63,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install samcat in ${PREFIX}/bin directory
 install (TARGETS samcat
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/samcat for SeqAn release builds.
diff --git a/apps/searchjoin/CMakeLists.txt b/apps/searchjoin/CMakeLists.txt
index 576df51..8fa1f28 100644
--- a/apps/searchjoin/CMakeLists.txt
+++ b/apps/searchjoin/CMakeLists.txt
@@ -12,6 +12,11 @@ message (STATUS "Configuring apps/searchjoin")
 
 set (SEQAN_APP_VERSION "0.5.7")
 
+if (SEQAN_TRAVIS_BUILD)
+    message (STATUS "  Skipping build and test of searchjoin on Travis CI.")
+    return ()
+endif (SEQAN_TRAVIS_BUILD)
+
 # ----------------------------------------------------------------------------
 # Dependencies
 # ----------------------------------------------------------------------------
@@ -30,20 +35,13 @@ endif ()
 include_directories (${SEQAN_INCLUDE_DIRS})
 
 # Add definitions set by find_package (SeqAn).
-add_definitions (${SEQAN_DEFINITIONS})
+add_definitions (${SEQAN_DEFINITIONS} -DSEARCHJOIN_HUGEDB=TRUE)
 
 # Add definitions set by the build system.
 add_definitions (-DSEQAN_APP_VERSION="${SEQAN_APP_VERSION}")
 add_definitions (-DSEQAN_REVISION="${SEQAN_REVISION}")
 add_definitions (-DSEQAN_DATE="${SEQAN_DATE}")
 
-# Lightweight CI builds.
-if (NOT SEQAN_TRAVIS_BUILD)
-    add_definitions (-DSEARCHJOIN_HUGEDB=TRUE)
-else (NOT SEQAN_TRAVIS_BUILD)
-    message (STATUS "  Building searchjoin without huge db support on Travis CI.")
-endif (NOT SEQAN_TRAVIS_BUILD)
-
 # Update the list of file names below if you add source files to your application.
 add_executable (s4_search search.cpp finder.h db.h verifier.h writer.h)
 add_executable (s4_join join.cpp finder.h db.h verifier.h writer.h)
@@ -66,7 +64,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install searchjoin in ${PREFIX}/bin directory
 install (TARGETS s4_search s4_join
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/searchjoin for SeqAn release builds.
diff --git a/apps/searchjoin/db.h b/apps/searchjoin/db.h
index bec0120..8d5e503 100644
--- a/apps/searchjoin/db.h
+++ b/apps/searchjoin/db.h
@@ -130,25 +130,25 @@ namespace seqan
 template <>
 struct Fibre<TDbDnaSaSmall, FibreSA>
 {
-    typedef String<Pair<unsigned int, unsigned char, BitPacked<24, 8> >, StringSpec<TDbDnaSaSmall>::Type> Type;
+    typedef String<Pair<unsigned int, unsigned char, BitPacked<24, 8> >, DefaultIndexStringSpec<TDbDnaSaSmall>::Type> Type;
 };
 
 template <>
 struct Fibre<TDbGeoSaSmall, FibreSA>
 {
-    typedef String<Pair<unsigned int, unsigned char, BitPacked<24, 8> >, StringSpec<TDbGeoSaSmall>::Type> Type;
+    typedef String<Pair<unsigned int, unsigned char, BitPacked<24, 8> >, DefaultIndexStringSpec<TDbGeoSaSmall>::Type> Type;
 };
 
 template <>
 struct Fibre<TDbDnaSaHuge, FibreSA>
 {
-    typedef String<Pair<unsigned int, unsigned char, Pack>, StringSpec<TDbDnaSaHuge>::Type> Type;
+    typedef String<Pair<unsigned int, unsigned char, Pack>, DefaultIndexStringSpec<TDbDnaSaHuge>::Type> Type;
 };
 
 template <>
 struct Fibre<TDbGeoSaHuge, FibreSA>
 {
-    typedef String<Pair<unsigned int, unsigned char, Pack>, StringSpec<TDbDnaSaHuge>::Type> Type;
+    typedef String<Pair<unsigned int, unsigned char, Pack>, DefaultIndexStringSpec<TDbDnaSaHuge>::Type> Type;
 };
 }
 
diff --git a/apps/seqan_tcoffee/CMakeLists.txt b/apps/seqan_tcoffee/CMakeLists.txt
index 66e85e2..c8df67c 100644
--- a/apps/seqan_tcoffee/CMakeLists.txt
+++ b/apps/seqan_tcoffee/CMakeLists.txt
@@ -56,7 +56,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install seqan_tcoffee in ${PREFIX}/bin directory
 install (TARGETS seqan_tcoffee
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/seqan_tcoffee for SeqAn release builds.
diff --git a/apps/seqan_tcoffee/tests/run_tests.py b/apps/seqan_tcoffee/tests/run_tests.py
index 53d7459..0d58a27 100755
--- a/apps/seqan_tcoffee/tests/run_tests.py
+++ b/apps/seqan_tcoffee/tests/run_tests.py
@@ -12,6 +12,7 @@ Usage:  run_tests.py SOURCE_ROOT_PATH BINARY_ROOT_PATH
 import logging
 import os.path
 import sys
+import platform
 
 # Automagically add util/py_lib to PYTHONPATH environment variable.
 path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
@@ -23,6 +24,11 @@ import seqan.app_tests as app_tests
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
+    if platform.machine().startswith('mips') or platform.machine().startswith('s390'):
+        print 'Skipping tests for seqan_tcoffee on mips* and s390*'
+        print '==================================================='
+        return 0
+
     print 'Executing test for seqan_tcoffee'
     print '================================'
     print
diff --git a/apps/seqcons2/CMakeLists.txt b/apps/seqcons2/CMakeLists.txt
index 8b5fcc2..8edf724 100644
--- a/apps/seqcons2/CMakeLists.txt
+++ b/apps/seqcons2/CMakeLists.txt
@@ -62,7 +62,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install seqcons2 in ${PREFIX}/bin directory
 install (TARGETS seqcons2
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/seqcons2 for SeqAn release builds.
diff --git a/apps/sgip/CMakeLists.txt b/apps/sgip/CMakeLists.txt
index 71a28ac..6f692c4 100755
--- a/apps/sgip/CMakeLists.txt
+++ b/apps/sgip/CMakeLists.txt
@@ -56,7 +56,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install sgip in ${PREFIX}/bin directory
 install (TARGETS sgip
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/sgip for SeqAn release builds.
diff --git a/apps/snp_store/CMakeLists.txt b/apps/snp_store/CMakeLists.txt
index e846ec3..797b248 100644
--- a/apps/snp_store/CMakeLists.txt
+++ b/apps/snp_store/CMakeLists.txt
@@ -71,7 +71,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install snp_store in ${PREFIX}/bin directory
 install (TARGETS snp_store
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/snp_store for SeqAn release builds.
diff --git a/apps/splazers/CMakeLists.txt b/apps/splazers/CMakeLists.txt
index bb85d5d..35c8386 100644
--- a/apps/splazers/CMakeLists.txt
+++ b/apps/splazers/CMakeLists.txt
@@ -68,7 +68,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install splazers in ${PREFIX}/bin directory
 install (TARGETS splazers
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/splazers for SeqAn release builds.
diff --git a/apps/stellar/CMakeLists.txt b/apps/stellar/CMakeLists.txt
index a94d1bf..f6e0499 100644
--- a/apps/stellar/CMakeLists.txt
+++ b/apps/stellar/CMakeLists.txt
@@ -60,7 +60,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install stellar in ${PREFIX}/bin directory
 install (TARGETS stellar
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/stellar for SeqAn release builds.
diff --git a/apps/stellar/stellar.cpp b/apps/stellar/stellar.cpp
index 604cd43..f253d47 100644
--- a/apps/stellar/stellar.cpp
+++ b/apps/stellar/stellar.cpp
@@ -569,7 +569,7 @@ void _setParser(ArgumentParser & parser)
     setDefaultValue(parser, "o", "stellar.gff");
     addOption(parser, ArgParseOption("od", "outDisabled",
                                      "Name of output file for disabled query sequences.", ArgParseArgument::OUTPUT_FILE));
-    setValidValues(parser, "outDisabled", "fa fasta");
+    setValidValues(parser, "outDisabled", seqan::SeqFileOut::getFileExtensions());
     setDefaultValue(parser, "od", "stellar.disabled.fasta");
     addOption(parser, ArgParseOption("t", "no-rt", "Suppress printing running time."));
     hideOption(parser, "t");
diff --git a/apps/tree_recon/CMakeLists.txt b/apps/tree_recon/CMakeLists.txt
index d39248f..2b9a4fc 100644
--- a/apps/tree_recon/CMakeLists.txt
+++ b/apps/tree_recon/CMakeLists.txt
@@ -56,7 +56,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install tree_recon in ${PREFIX}/bin directory
 install (TARGETS tree_recon
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/tree_recon for SeqAn release builds.
diff --git a/apps/yara/CMakeLists.txt b/apps/yara/CMakeLists.txt
index 73ec26a..fd14881 100644
--- a/apps/yara/CMakeLists.txt
+++ b/apps/yara/CMakeLists.txt
@@ -136,7 +136,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install yara in ${PREFIX}/bin directory
 install (TARGETS yara_indexer yara_mapper
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/yara for SeqAn release builds.
diff --git a/apps/yara/find_verifier.h b/apps/yara/find_verifier.h
index cb1ce9d..66c06cd 100644
--- a/apps/yara/find_verifier.h
+++ b/apps/yara/find_verifier.h
@@ -48,15 +48,15 @@ using namespace seqan;
 template <typename THaystack, typename TNeedle, typename TSpec>
 struct Verifier
 {
-    typedef typename InfixOnValue<THaystack const>::Type THaystackInfix;
-    typedef String<GapAnchor<int> >                      TGapAnchors;
-    typedef AnchorGaps<TGapAnchors>                      TAnchorGaps;
-    typedef typename Size<THaystackInfix>::Type          TSize;
-    typedef typename Position<THaystackInfix>::Type      TPosition;
-    typedef TraceSegment_<TPosition, TSize>              TTraceSegment;
-    typedef String<TTraceSegment>                        TTrace;
-    typedef DPScoutState_<Default>                       TDPState;
-    typedef DPContext<int, AffineGaps>                   TDPContext;
+    typedef typename InfixOnValue<THaystack const>::Type                        THaystackInfix;
+    typedef String<GapAnchor<int> >                                             TGapAnchors;
+    typedef AnchorGaps<TGapAnchors>                                             TAnchorGaps;
+    typedef typename Size<THaystackInfix>::Type                                 TSize;
+    typedef typename Position<THaystackInfix>::Type                             TPosition;
+    typedef TraceSegment_<TPosition, TSize>                                     TTraceSegment;
+    typedef String<TTraceSegment>                                               TTrace;
+    typedef DPScoutState_<Default>                                              TDPState;
+    typedef DPContext<DPCell_<int, AffineGaps>, typename TraceBitMap_<>::Type>  TDPContext;
 
     // Thread-private data.
     TGapAnchors     contigAnchors;
diff --git a/demos/tutorial/file_io_overview/solution3.cpp.stdout b/demos/tutorial/file_io_overview/solution3.cpp.stdout
index 93d2747..ea243b5 100644
--- a/demos/tutorial/file_io_overview/solution3.cpp.stdout
+++ b/demos/tutorial/file_io_overview/solution3.cpp.stdout
@@ -1,9 +1,9 @@
 @HD	VN:1.3	SO:coordinate
 @SQ	SN:ref	LN:45
 @SQ	SN:ref2	LN:40
-r001	163	ref	7	30	8M4I4M1D3M	=	37	39	TTAGATAAAGAGGATACTG	                   	XX:B:S,12561,2,20,112
-r002	0	ref	9	30	1S2I6M1P1I1P1I4M2I	*	0	0	AAAAGATAAGGGATAAA	                 
-r003	0	ref	9	30	5H6M	*	0	0	AGCTAA	      
-r004	0	ref	16	30	6M14N1I5M	*	0	0	ATAGCTCTCAGC	            
-r003	16	ref	29	30	6H5M	*	0	0	TAGGC	     
-r001	83	ref	37	30	9M	=	7	-39	CAGCGCCAT	         
+r001	163	ref	7	30	8M4I4M1D3M	=	37	39	TTAGATAAAGAGGATACTG	*	XX:B:S,12561,2,20,112
+r002	0	ref	9	30	1S2I6M1P1I1P1I4M2I	*	0	0	AAAAGATAAGGGATAAA	*
+r003	0	ref	9	30	5H6M	*	0	0	AGCTAA	*
+r004	0	ref	16	30	6M14N1I5M	*	0	0	ATAGCTCTCAGC	*
+r003	16	ref	29	30	6H5M	*	0	0	TAGGC	*
+r001	83	ref	37	30	9M	=	7	-39	CAGCGCCAT	*
diff --git a/demos/tutorial/indices/find2_index_approx.cpp b/demos/tutorial/indices/find2_index_approx.cpp
new file mode 100644
index 0000000..ca675f7
--- /dev/null
+++ b/demos/tutorial/indices/find2_index_approx.cpp
@@ -0,0 +1,57 @@
+//![Complete]
+#include <set>
+#include <mutex>
+
+#include <seqan/index.h>
+
+using namespace seqan;
+
+int main()
+{
+
+    DnaString genome(
+        "GAGAGGCCACTCGCAGGATTAAGTCAATAAGTTAATGGCGTGGGGTTATGGTATGGGGGTTCTCGCCCACAGTGACCTCATCGGT"
+        "GCATTTCCTCATCGTAGGCGGAACGGTAGACACAAGGCATGATGTCAAATCGCGACTCCAATCCCAAGGTCGCAAGCCTATATAG"
+        "GAACCCGCTTATGCCCTCTAATCCCGGACAGACCCCAAATATGGCATAGCTGGTTGGGGGTACCTACTAGGCACAGCCGGAAGCA");
+    Index<DnaString, BidirectionalIndex<FMIndex<> > > index(genome);
+
+    //![Delegate]
+    auto delegate = [](auto & iter, DnaString const & needle, uint8_t errors)
+    {
+        for (auto occ : getOccurrences(iter))
+            std::cout << occ << std::endl;
+    };
+    //![Delegate]
+
+    DnaString pattern("GGGGTTAT");
+    std::cout << "Hits with up to 2 errors (HammingDistance):" << std::endl;
+    //![SinglePattern]
+    find<0, 2>(delegate, index, pattern, HammingDistance());
+    //![SinglePattern]
+
+    StringSet<DnaString> patterns;
+    appendValue(patterns, "GGGGTTAT");
+    appendValue(patterns, "CTAGCTAA");
+    std::cout << "Hits with 1-2 errors (HammingDistance):" << std::endl;
+    //![MultiplePatterns]
+    find<1, 2>(delegate, index, patterns, HammingDistance(), Serial());
+    //![MultiplePatterns]
+
+    //![ParallelMode]
+    std::mutex mtx;
+    std::set<Pair<DnaString, unsigned> > hits;
+    auto delegateParallel = [&hits, &mtx](auto & iter, DnaString const & needle, uint8_t errors)
+    {
+        std::lock_guard<std::mutex> lck(mtx); // critical section below this line
+        for (auto occ : getOccurrences(iter))
+            hits.insert(Pair<DnaString, unsigned>(needle, occ));
+    };
+    find<2, 3>(delegateParallel, index, patterns, HammingDistance(), Parallel());
+    std::cout << "Hits with 2-3 errors (HammingDistance, no duplicates):" << std::endl;
+    for (auto hit : hits)
+        std::cout << hit << std::endl;
+    //![ParallelMode]
+
+    return 0;
+}
+//![Complete]
diff --git a/demos/tutorial/indices/find2_index_approx.stdout b/demos/tutorial/indices/find2_index_approx.stdout
new file mode 100644
index 0000000..a0a07c7
--- /dev/null
+++ b/demos/tutorial/indices/find2_index_approx.stdout
@@ -0,0 +1,23 @@
+Hits with up to 2 errors (HammingDistance):
+225
+41
+55
+Hits with 1-2 errors (HammingDistance):
+225
+55
+Hits with 1-2 errors (EditDistance, no duplicates):
+< CTAGCTAA , 27 >
+< CTAGCTAA , 61 >
+< CTAGCTAA , 157 >
+< CTAGCTAA , 162 >
+< CTAGCTAA , 173 >
+< CTAGCTAA , 183 >
+< CTAGCTAA , 215 >
+< CTAGCTAA , 229 >
+< CTAGCTAA , 236 >
+< GGGGTTAT , 14 >
+< GGGGTTAT , 54 >
+< GGGGTTAT , 120 >
+< GGGGTTAT , 174 >
+< GGGGTTAT , 225 >
+< GGGGTTAT , 226 >
diff --git a/demos/tutorial/sam_and_bam_io/example7.cpp.stdout b/demos/tutorial/sam_and_bam_io/example7.cpp.stdout
index b87004f..eea4906 100644
--- a/demos/tutorial/sam_and_bam_io/example7.cpp.stdout
+++ b/demos/tutorial/sam_and_bam_io/example7.cpp.stdout
@@ -1,3 +1,3 @@
-r002	0	ref	9	30	1S2I6M1P1I1P1I4M2I	*	0	0	AAAAGATAAGGGATAAA	                 
-r003	0	ref	9	30	5H6M	*	0	0	AGCTAA	      
-r004	0	ref	16	30	6M14N1I5M	*	0	0	ATAGCTCTCAGC	            
+r002	0	ref	9	30	1S2I6M1P1I1P1I4M2I	*	0	0	AAAAGATAAGGGATAAA	*
+r003	0	ref	9	30	5H6M	*	0	0	AGCTAA	*
+r004	0	ref	16	30	6M14N1I5M	*	0	0	ATAGCTCTCAGC	*
diff --git a/dox/CMakeLists.txt b/dox/CMakeLists.txt
index 74b4749..e5e1189 100644
--- a/dox/CMakeLists.txt
+++ b/dox/CMakeLists.txt
@@ -39,5 +39,5 @@ if (${SEQAN_BUILD_SYSTEM} MATCHES "SEQAN_RELEASE_LIBRARY") # includes SEQAN_RELE
         --out-dir ${CMAKE_BINARY_DIR}/dox/html)
 
     install (DIRECTORY ${CMAKE_BINARY_DIR}/dox/html
-             DESTINATION share/doc/seqan)
+             DESTINATION ${CMAKE_INSTALL_DOCDIR})
 endif ()
diff --git a/include/seqan/align.h b/include/seqan/align.h
index 083a08f..e6aa487 100644
--- a/include/seqan/align.h
+++ b/include/seqan/align.h
@@ -77,6 +77,8 @@
 
 #include <seqan/align/fragment.h>
 
+#include <seqan/align/aligned_sequence_concept.h>
+
 #include <seqan/align/gaps_base.h>
 #include <seqan/align/gaps_iterator_base.h>
 
diff --git a/include/seqan/align/align_interface_wrapper.h b/include/seqan/align/align_interface_wrapper.h
index 6baafa0..915c16b 100644
--- a/include/seqan/align/align_interface_wrapper.h
+++ b/include/seqan/align/align_interface_wrapper.h
@@ -58,14 +58,20 @@ namespace seqan
 // Function _alignWrapperSequential(); Score; StringSet vs. StringSet
 // ----------------------------------------------------------------------------
 
-template <typename TString1, typename TSpec1,
-          typename TString2, typename TSpec2,
+template <typename TSetH,
+          typename TSetV,
           typename TScoreValue, typename TScoreSpec,
           typename TAlignConfig,
-          typename TGapModel>
+          typename TGapModel,
+          std::enable_if_t<And<And<Is<ContainerConcept<TSetH>>,
+                                   Is<ContainerConcept<typename Value<TSetH>::Type>>>,
+                               And<Is<ContainerConcept<TSetV>>,
+                                   Is<ContainerConcept<typename Value<TSetV>::Type>>>
+                               >::VALUE,
+                           int> = 0>
 inline auto
-_alignWrapperSequential(StringSet<TString1, TSpec1> const & stringsH,
-                        StringSet<TString2, TSpec2> const & stringsV,
+_alignWrapperSequential(TSetH const & stringsH,
+                        TSetV const & stringsV,
                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
                         TAlignConfig const & config,
                         TGapModel const & /*gaps*/)
@@ -92,14 +98,20 @@ _alignWrapperSequential(StringSet<TString1, TSpec1> const & stringsH,
 // Function _alignWrapperSequential(); Score; String vs. StringSet
 // ----------------------------------------------------------------------------
 
-template <typename TString1,
-          typename TString2, typename TSpec,
+template <typename TSeqH,
+          typename TSetV,
           typename TScoreValue, typename TScoreSpec,
           typename TAlignConfig,
-          typename TGapModel>
+          typename TGapModel,
+          std::enable_if_t<And<And<Is<ContainerConcept<TSeqH>>,
+                                   Not<Is<ContainerConcept<typename Value<TSeqH>::Type>>>>,
+                               And<Is<ContainerConcept<TSetV>>,
+                                   Is<ContainerConcept<typename Value<TSetV>::Type>>>
+                               >::VALUE,
+                           int> = 0>
 inline auto
-_alignWrapperSequential(TString1 const & stringH,
-                        StringSet<TString2, TSpec> const & stringsV,
+_alignWrapperSequential(TSeqH const & stringH,
+                        TSetV const & stringsV,
                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
                         TAlignConfig const & config,
                         TGapModel const & /*gaps*/)
@@ -125,21 +137,27 @@ _alignWrapperSequential(TString1 const & stringH,
 // Function _alignWrapperSequential(); Gaps
 // ----------------------------------------------------------------------------
 
-template <typename TSequenceH, typename TGapsSpecH, typename TSetSpecH,
-          typename TSequenceV, typename TGapsSpecV, typename TSetSpecV,
+template <typename TSetH,
+          typename TSetV,
           typename TScoreValue, typename TScoreSpec,
           typename TAlignConfig,
-          typename TGapModel>
+          typename TGapModel,
+          std::enable_if_t<And<And<Is<ContainerConcept<TSetH>>,
+                                   Is<AlignedSequenceConcept<typename Value<TSetH>::Type>>>,
+                               And<Is<ContainerConcept<TSetV>>,
+                                   Is<AlignedSequenceConcept<typename Value<TSetV>::Type>>>
+                               >::VALUE,
+                           int> = 0>
 inline auto
-_alignWrapperSequential(StringSet<Gaps<TSequenceH, TGapsSpecH>, TSetSpecH> & gapSeqSetH,
-                        StringSet<Gaps<TSequenceV, TGapsSpecV>, TSetSpecV> & gapSeqSetV,
+_alignWrapperSequential(TSetH & gapSeqSetH,
+                        TSetV & gapSeqSetV,
                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
                         TAlignConfig const & config,
                         TGapModel const & /*gaps*/)
 
 {
-    typedef typename Size<TSequenceH>::Type TSize;
-    typedef typename Position<TSequenceH>::Type TPosition;
+    typedef typename Size<TSetH>::Type TSize;
+    typedef typename Position<TSetH>::Type TPosition;
     typedef TraceSegment_<TPosition, TSize> TTraceSegment;
 
     String<TScoreValue> results;
diff --git a/include/seqan/parallel/parallel_tags.h b/include/seqan/align/aligned_sequence_concept.h
similarity index 69%
copy from include/seqan/parallel/parallel_tags.h
copy to include/seqan/align/aligned_sequence_concept.h
index 20d395c..0de2624 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/include/seqan/align/aligned_sequence_concept.h
@@ -29,15 +29,14 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tags to select serial/parallel algorithms.
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
-#define SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#ifndef INCLUDE_SEQAN_ALIGN_ALIGNED_SEQUENCE_CONCEPT_H_
+#define INCLUDE_SEQAN_ALIGN_ALIGNED_SEQUENCE_CONCEPT_H_
 
-namespace seqan {
+namespace seqan
+{
 
 // ============================================================================
 // Forwards
@@ -47,40 +46,20 @@ namespace seqan {
 // Tags, Classes, Enums
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Tag Parallel
-// ----------------------------------------------------------------------------
-
-/*!
- * @defgroup ParallelismTags Parallelism Tags
- * @brief Tags for enabling/disabling parallelism.
- *
- * @tag ParallelismTags#Parallel
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the parallel implementation of an algorithm.
- *
- * @tag ParallelismTags#Serial
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the serial implementation of an algorithm.
- */
+SEQAN_CONCEPT_REFINE(AlignedSequenceConcept, (TSequence), (ContainerConcept))
+{
 
-struct Parallel_;
-typedef Tag<Parallel_> Parallel;
+    SEQAN_CONCEPT_USAGE(AlignedSequenceConcept)
+    {}
+};
 
 // ============================================================================
 // Metafunctions
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Metafunction DefaultParallelSpec
-// ----------------------------------------------------------------------------
-
-template <typename TObject>
-struct DefaultParallelSpec
-{
-    typedef Parallel Type;
-};
-
+// ============================================================================
+// Functions
+// ============================================================================
 }  // namespace seqan
 
-#endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_ALIGNED_SEQUENCE_CONCEPT_H_
diff --git a/include/seqan/align/dp_algorithm_impl.h b/include/seqan/align/dp_algorithm_impl.h
index 88736ba..8877e45 100644
--- a/include/seqan/align/dp_algorithm_impl.h
+++ b/include/seqan/align/dp_algorithm_impl.h
@@ -272,16 +272,18 @@ _isBandEnabled(DPBandConfig<TBandSpec> const & /*band*/)
 // ----------------------------------------------------------------------------
 
 // Computes the score and tracks it if enabled.
-template <typename TDPScout, typename TTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
+template <typename TDPScout,
+          typename TTraceMatrixNavigator,
+          typename TDPCell,
           typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme, typename TColumnDescriptor,
           typename TCellDescriptor, typename TDPProfile>
 inline void
 _computeCell(TDPScout & scout,
              TTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const & previousDiagonal,
-             DPCell_<TScoreValue, TGapCosts> const & previousHorizontal,
-             DPCell_<TScoreValue, TGapCosts> const & previousVertical,
+             TDPCell & current,
+             TDPCell & diagonal,
+             TDPCell const & horizontal,
+             TDPCell & vertical,
              TSequenceHValue const & seqHVal,
              TSequenceVValue const & seqVVal,
              TScoringScheme const & scoringScheme,
@@ -290,16 +292,23 @@ _computeCell(TDPScout & scout,
              TDPProfile const &)
 {
     typedef DPMetaColumn_<TDPProfile, TColumnDescriptor> TMetaColumn;
+
     assignValue(traceMatrixNavigator,
-                _computeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal, seqVVal,
-                              scoringScheme, typename RecursionDirection_<TMetaColumn, TCellDescriptor>::Type(),
+                _computeScore(current, diagonal, horizontal, vertical, seqHVal, seqVVal, scoringScheme,
+                              typename RecursionDirection_<TMetaColumn, TCellDescriptor>::Type(),
                               TDPProfile()));
 
     if (TrackingEnabled_<TMetaColumn, TCellDescriptor>::VALUE)
     {
         typedef typename LastColumnEnabled_<TDPProfile, TColumnDescriptor>::Type TIsLastColumn;
         typedef typename LastRowEnabled_<TDPProfile, TCellDescriptor, TColumnDescriptor>::Type TIsLastRow;
-        _scoutBestScore(scout, activeCell, traceMatrixNavigator,
+
+        // TODO(rrahn): Refactor to set vertical score only when max is updated.
+        if (IsTracebackEnabled_<TDPProfile>::VALUE)
+        {
+            _setVerticalScoreOfCell(current, _verticalScoreOfCell(vertical));
+        }
+        _scoutBestScore(scout, current, traceMatrixNavigator,
                         TIsLastColumn(), TIsLastRow());
     }
 }
@@ -322,10 +331,16 @@ _precomputeScoreMatrixOffset(TSeqValue const & seqVal,
 // Function _computeTrack()
 // ----------------------------------------------------------------------------
 
-// Computes one track of the dp algorithm. A track is defined as the area that is filled by the inner loop and
-// iterated by the outer loop. For the column-wise navigation the track is equivalent with the column.
-template <typename TDPScout, typename TDPScoreMatrixNavigator, typename TDPTraceMatrixNavigator, typename TSeqHValue,
-          typename TSeqVValue, typename TSeqVIterator, typename TScoringScheme, typename TColumnDescriptor, typename TDPProfile>
+template <typename TDPScout,
+          typename TDPScoreMatrixNavigator,
+          typename TDPTraceMatrixNavigator,
+          typename TSeqHValue,
+          typename TSeqVValue,
+          typename TSeqVIterator,
+          typename TScoringScheme,
+          typename TDPCell,
+          typename TColumnDescriptor,
+          typename TDPProfile>
 inline void
 _computeTrack(TDPScout & scout,
               TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
@@ -335,13 +350,16 @@ _computeTrack(TDPScout & scout,
               TSeqVIterator const & seqBegin,
               TSeqVIterator const & seqEnd,
               TScoringScheme const & scoringScheme,
+              TDPCell & cacheDiag,
+              TDPCell & cacheVert,
               TColumnDescriptor const &,
               TDPProfile const &)
 {
-    // Set the iterator to the begin of the track.
     _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), FirstCell());
     _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), FirstCell());
 
+    _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, TColumnDescriptor());
+
     // Precompute the row of the scoring matrix for future look-ups.
     TSeqHValue tmpSeqH = _precomputeScoreMatrixOffset(seqHValue, scoringScheme);
 
@@ -349,53 +367,93 @@ _computeTrack(TDPScout & scout,
     _preInitScoutVertical(scout);
 
     // Compute the first cell.
-    _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                 previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                 previousCellVertical(dpScoreMatrixNavigator), tmpSeqH, seqVValue, scoringScheme,
+    _computeCell(scout,
+                 dpTraceMatrixNavigator,
+                 value(dpScoreMatrixNavigator),
+                           cacheDiag,
+                           previousCellHorizontal(dpScoreMatrixNavigator),
+                           cacheVert,
+                 tmpSeqH,
+                 seqVValue,
+                 scoringScheme,
                  TColumnDescriptor(), FirstCell(), TDPProfile());
 
     TSeqVIterator iter = seqBegin;
-    TSeqVIterator itEnd = (seqEnd - 1);
-    // Compute the inner cells of the current track.
-    for (; iter != itEnd; ++iter)
+    for (; iter != seqEnd - 1; ++iter)
     {
-        _incVerticalPos(scout);
-        // Set the iterator to the next cell within the track.
         _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), InnerCell());
         _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), InnerCell());
+
+        _incVerticalPos(scout);
         // Compute the inner cell.
-        // If we have variable length simd, we need to check if we reached the end of one of the sequences.
-        // For all other cases, the function returns always false.
         if (SEQAN_UNLIKELY(_reachedVerticalEndPoint(scout, iter)))
         {
-            _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                         previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                         previousCellVertical(dpScoreMatrixNavigator), tmpSeqH,
-                         sequenceEntryForScore(scoringScheme, container(iter), position(iter)), scoringScheme,
-                         TColumnDescriptor(), LastCell(), TDPProfile());
+            _computeCell(scout,
+                         dpTraceMatrixNavigator,
+                         value(dpScoreMatrixNavigator),
+                         cacheDiag,
+                         previousCellHorizontal(dpScoreMatrixNavigator),
+                         cacheVert,
+                         tmpSeqH, sequenceEntryForScore(scoringScheme, container(iter), position(iter)),
+                         scoringScheme, TColumnDescriptor(), LastCell(), TDPProfile());
             _nextVerticalEndPos(scout);
         }
         else
         {
-            _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                         previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                         previousCellVertical(dpScoreMatrixNavigator), tmpSeqH,
-                         sequenceEntryForScore(scoringScheme, container(iter), position(iter)), scoringScheme,
-                         TColumnDescriptor(), InnerCell(), TDPProfile());
+            _computeCell(scout,
+                         dpTraceMatrixNavigator,
+                         value(dpScoreMatrixNavigator),
+                         cacheDiag,
+                         previousCellHorizontal(dpScoreMatrixNavigator),
+                         cacheVert,
+                         tmpSeqH, sequenceEntryForScore(scoringScheme, container(iter), position(iter)),
+                         scoringScheme, TColumnDescriptor(), InnerCell(), TDPProfile());
         }
     }
-    _incVerticalPos(scout);
-    // Set the iterator to the last cell of the track.
     _goNextCell(dpScoreMatrixNavigator, TColumnDescriptor(), LastCell());
     _goNextCell(dpTraceMatrixNavigator, TColumnDescriptor(), LastCell());
-    // Compute the last cell.
-    _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                 previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                 previousCellVertical(dpScoreMatrixNavigator), tmpSeqH,
-                 sequenceEntryForScore(scoringScheme, container(iter), position(iter)), scoringScheme,
+    _incVerticalPos(scout);
+    _computeCell(scout,
+                 dpTraceMatrixNavigator,
+                 value(dpScoreMatrixNavigator),
+                           cacheDiag,
+                           previousCellHorizontal(dpScoreMatrixNavigator),
+                           cacheVert,
+                 tmpSeqH,
+                 sequenceEntryForScore(scoringScheme, container(iter), position(iter)),
+                 scoringScheme,
                  TColumnDescriptor(), LastCell(), TDPProfile());
 }
 
+template <typename TDPScout,
+          typename TDPScoreMatrixNavigator,
+          typename TDPTraceMatrixNavigator,
+          typename TSeqHValue,
+          typename TSeqVValue,
+          typename TSeqVIterator,
+          typename TScoringScheme,
+          typename TColumnDescriptor,
+          typename TDPProfile>
+inline void
+_computeTrack(TDPScout & scout,
+              TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
+              TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
+              TSeqHValue const & seqHValue,
+              TSeqVValue const & seqVValue,
+              TSeqVIterator const & seqBegin,
+              TSeqVIterator const & seqEnd,
+              TScoringScheme const & scoringScheme,
+              TColumnDescriptor const &,
+              TDPProfile const &)
+{
+    using TDPCell = std::decay_t<decltype(value(dpScoreMatrixNavigator))>;
+
+    TDPCell cacheDiag;
+    TDPCell cacheVert;
+    _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqHValue, seqVValue, seqBegin, seqEnd,
+                  scoringScheme, cacheDiag, cacheVert, TColumnDescriptor{}, TDPProfile{});
+}
+
 // ----------------------------------------------------------------------------
 // Function _computeUnbandedAlignmentHelperTerminate()
 // ----------------------------------------------------------------------------
@@ -419,16 +477,24 @@ _computeAlignmentHelperCheckTerminate(DPScout_<TDPCell,Terminator_<TSpec> > cons
 // ----------------------------------------------------------------------------
 
 // Computes the standard DP-algorithm.
-template <typename TDPScout, typename TDPScoreMatrixNavigator, typename TDPTraceMatrixNavigator, typename TSequenceH,
-          typename TSequenceV, typename TScoringScheme, typename TAlignmentAlgo, typename TGapCosts, typename TTraceFlag>
+template <typename TDPScout,
+          typename TDPScoreMatrixNavigator,
+          typename TDPTraceMatrixNavigator,
+          typename TSequenceH,
+          typename TSequenceV,
+          typename TScoringScheme,
+          typename TBand,
+          typename TAlignmentAlgo, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
 inline void
-_computeUnbandedAlignment(TDPScout & scout,
-                          TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
-                          TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
-                          TSequenceH const & seqH,
-                          TSequenceV const & seqV,
-                          TScoringScheme const & scoringScheme,
-                          DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag> const & dpProfile)
+_computeAlignmentImpl(TDPScout & scout,
+                      TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
+                      TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
+                      TSequenceH const & seqH,
+                      TSequenceV const & seqV,
+                      TScoringScheme const & scoringScheme,
+                      TBand const & /*band*/,
+                      DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag, TExecPolicy> const & dpProfile,
+                      NavigateColumnWise const & /*tag*/)
 {
     typedef typename Iterator<TSequenceH const, Rooted>::Type TConstSeqHIterator;
     typedef typename Iterator<TSequenceV const, Rooted>::Type TConstSeqVIterator;
@@ -445,6 +511,7 @@ _computeUnbandedAlignment(TDPScout & scout,
 
     SEQAN_ASSERT_GT(length(seqH), 0u);
     SEQAN_ASSERT_GT(length(seqV), 0u);
+
     _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
                   sequenceEntryForScore(scoringScheme, seqH, 0),
                   sequenceEntryForScore(scoringScheme, seqV, 0),
@@ -487,6 +554,7 @@ _computeUnbandedAlignment(TDPScout & scout,
     // ============================================================================
     // POSTPROCESSING
     // ============================================================================
+
     _incHorizontalPos(scout);
     _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
                   sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
@@ -505,22 +573,28 @@ _computeUnbandedAlignment(TDPScout & scout,
 }
 
 // ----------------------------------------------------------------------------
-// Function _computeBandedAlignment()
+// Function _computeAlignment() banded
 // ----------------------------------------------------------------------------
 
 // Computes the banded DP-algorithm.
-template <typename TDPScout, typename TDPScoreMatrixNavigator, typename TDPTraceMatrixNavigator, typename TSequenceH,
-          typename TSequenceV, typename TScoringScheme, typename TBand, typename TAlignmentAlgo, typename TGapCosts,
-          typename TTraceFlag>
+template <typename TDPScout,
+          typename TDPScoreMatrixNavigator,
+          typename TDPTraceMatrixNavigator,
+          typename TSequenceH,
+          typename TSequenceV,
+          typename TScoringScheme,
+          typename TBand,
+          typename TAlignmentAlgo, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
 inline void
-_computeBandedAlignment(TDPScout & scout,
-                        TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
-                        TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
-                        TSequenceH const & seqH,
-                        TSequenceV const & seqV,
-                        TScoringScheme const & scoringScheme,
-                        TBand const & band,
-                        DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag> const & dpProfile)
+_computeAlignmentImpl(TDPScout & scout,
+                      TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
+                      TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
+                      TSequenceH const & seqH,
+                      TSequenceV const & seqV,
+                      TScoringScheme const & scoringScheme,
+                      TBand const & band,
+                      DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag, TExecPolicy> const & dpProfile,
+                      NavigateColumnWiseBanded const & /*tag*/)
 {
     typedef DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag> TDPProfile;
     typedef typename MakeSigned<typename Size<TSequenceH>::Type>::Type TSignedSizeSeqH;
@@ -528,7 +602,17 @@ _computeBandedAlignment(TDPScout & scout,
     typedef typename Iterator<TSequenceH const, Rooted>::Type TConstSeqHIterator;
     typedef typename Iterator<TSequenceV const, Rooted>::Type TConstSeqVIterator;
 
+    using TDPScoreValue = std::decay_t<decltype(value(dpScoreMatrixNavigator))>;
+    // Caching these cells improves performance significantly.
+    TDPScoreValue cacheDiag;
+    TDPScoreValue cacheVert;
 
+    if (upperDiagonal(band) == lowerDiagonal(band))
+    {
+        _computeHammingDistance(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoringScheme, band,
+                                dpProfile);
+        return;
+    }
     // Now we have the problem of not knowing when we are in the last cell.
 
     // ============================================================================
@@ -570,8 +654,7 @@ _computeBandedAlignment(TDPScout & scout,
         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
         // Only one cell
         _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                     previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                     previousCellVertical(dpScoreMatrixNavigator),
+                     cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
                      sequenceEntryForScore(scoringScheme, seqH, position(seqHIterBegin)),
                      sequenceEntryForScore(scoringScheme, seqV, 0), scoringScheme,
                      MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell(), TDPProfile());
@@ -587,8 +670,7 @@ _computeBandedAlignment(TDPScout & scout,
         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
         // Only one cell
         _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                     previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                     previousCellVertical(dpScoreMatrixNavigator),
+                     cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
                      sequenceEntryForScore(scoringScheme, seqH, 0),
                      sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)), scoringScheme,
                      MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
@@ -619,10 +701,10 @@ _computeBandedAlignment(TDPScout & scout,
         // Set the iterator to the begin of the track.
         _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
+        //TODO(rrahn): We possibly need to set the cache values here?
         // Should we not just compute the cell?
         _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                     previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                     previousCellVertical(dpScoreMatrixNavigator),
+                     cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
                      sequenceEntryForScore(scoringScheme, seqH, position(seqHIterBegin)),
                      sequenceEntryForScore(scoringScheme, seqV, 0),
                      scoringScheme,
@@ -632,19 +714,24 @@ _computeBandedAlignment(TDPScout & scout,
             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), False());
     }
     else  // Upper diagonal >= 0 and lower Diagonal < 0
-    if (lowerDiagonal(band) <= -seqVlength)      // The band is bounded by the top and bottom of the matrix.
-        _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-                      sequenceEntryForScore(scoringScheme, seqH, 0),
-                      sequenceEntryForScore(scoringScheme, seqV, 0),
-                      seqVBegin, seqVEnd, scoringScheme,
-                      MetaColumnDescriptor<DPInitialColumn, FullColumn>(), dpProfile);
-    else       // The band is bounded by the top but not the bottom of the matrix.
-        _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-                      sequenceEntryForScore(scoringScheme, seqH, 0),
-                      sequenceEntryForScore(scoringScheme, seqV, 0),
-                      seqVBegin, seqVEnd, scoringScheme,
-                      MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), dpProfile);
-
+    {
+        if (lowerDiagonal(band) <= -seqVlength)      // The band is bounded by the top and bottom of the matrix.
+        {
+            _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
+                          sequenceEntryForScore(scoringScheme, seqH, 0),
+                          sequenceEntryForScore(scoringScheme, seqV, 0),
+                          seqVBegin, seqVEnd, scoringScheme,
+                          MetaColumnDescriptor<DPInitialColumn, FullColumn>(), dpProfile);
+        }
+        else       // The band is bounded by the top but not the bottom of the matrix.
+        {
+            _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
+                          sequenceEntryForScore(scoringScheme, seqH, 0),
+                          sequenceEntryForScore(scoringScheme, seqV, 0),
+                          seqVBegin, seqVEnd, scoringScheme,
+                          MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), dpProfile);
+        }
+    }
     if (_computeAlignmentHelperCheckTerminate(scout))
     {
             return;
@@ -744,16 +831,20 @@ _computeBandedAlignment(TDPScout & scout,
         _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
 
+        _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>());
+
         _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                     previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                     previousCellVertical(dpScoreMatrixNavigator),
+                     cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
                      sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
                      sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)),
                      scoringScheme,
                      MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
         // We might need to additionally track this point.
         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom> >, LastCell>::VALUE)
+        {
+            _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert));
             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, False(), True());
+        }
     }
     else if (seqHIter == end(seqH, Rooted()) - 1) // Case 2: The band ends somewhere in the final column of the matrix.
     {
@@ -764,16 +855,20 @@ _computeBandedAlignment(TDPScout & scout,
             _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
             _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
 
+            _preInitCacheDiagonal(cacheDiag, dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>());
+
             _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-                         previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-                         previousCellVertical(dpScoreMatrixNavigator),
+                         cacheDiag, previousCellHorizontal(dpScoreMatrixNavigator), cacheVert,
                          sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
                          sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin)),
                          scoringScheme,
                          MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
             // we might need to additionally track this point.
             if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom> >, LastCell>::VALUE)
+            {
+                _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert));
                 _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True());
+            }
         }
         else  // Case2b: At least two cells intersect between the band and the matrix in the final column of the matrix.
         {
@@ -796,10 +891,13 @@ _computeBandedAlignment(TDPScout & scout,
                         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
                                       sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
                                       sequenceEntryForScore(scoringScheme, seqV, 0),
-                                      seqVBegin, seqVEnd, scoringScheme,
+                                      seqVBegin, seqVEnd, scoringScheme, cacheDiag, cacheVert,
                                       MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), dpProfile);
                         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >, LastCell>::VALUE)
+                        {
+                            _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert));
                             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True());
+                        }
                     }
                     else
                         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
@@ -821,10 +919,13 @@ _computeBandedAlignment(TDPScout & scout,
                         _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
                                       sequenceEntryForScore(scoringScheme, seqH, position(seqHIter)),
                                       sequenceEntryForScore(scoringScheme, seqV, position(seqVBegin) - 1),
-                                      seqVBegin, seqVEnd, scoringScheme,
+                                      seqVBegin, seqVEnd, scoringScheme, cacheDiag, cacheVert,
                                       MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), dpProfile);
                         if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom> >, LastCell>::VALUE)
+                        {
+                            _setVerticalScoreOfCell(value(dpScoreMatrixNavigator), _verticalScoreOfCell(cacheVert));
                             _scoutBestScore(scout, value(dpScoreMatrixNavigator), dpTraceMatrixNavigator, True(), True());
+                        }
                     }
                     else
                     {
@@ -844,334 +945,24 @@ _computeBandedAlignment(TDPScout & scout,
                                   seqVBegin, seqVEnd, scoringScheme,
                                   MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), dpProfile);
                 }
-
             }
         }
     }
 }
 
-// TODO(rmaerker): This is denbug code only.
-//template <typename TDPScout, typename TDPScoreMatrixNavigator, typename TDPTraceMatrixNavigator, typename TSequenceH,
-//    typename TSequenceV, typename TScoringScheme, typename TBand, typename TAlignmentAlgo, typename TGapCosts,
-//    typename TTraceFlag>
-//inline void
-//_debugBandedAlignment(TDPScout & scout,
-//                        TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
-//                        TDPTraceMatrixNavigator & dpTraceMatrixNavigator,
-//                        TSequenceH const & seqH,
-//                        TSequenceV const & seqV,
-//                        TScoringScheme const & scoringScheme,
-//                        TBand const & band,
-//                        DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag> const & dpProfile)
-//{
-//    typedef DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag> TDPProfile;
-//    typedef typename Value<TSequenceH>::Type TSeqHValue;
-//    typedef typename Value<TSequenceV>::Type TSeqVValue;
-//    typedef typename Iterator<TSequenceH const, Standard>::Type TConstSeqHIterator;
-//    typedef typename Iterator<TSequenceV const, Standard>::Type TConstSeqVIterator;
-//
-//
-//    String<std::string> testMatrix;
-//    resize(testMatrix, (length(seqH) + 1) * (length(seqV)+1));
-//    // Now we have the problem of not knowing when we are in the last cell.
-//
-//    // INITIALIZATION
-//    TConstSeqVIterator seqVBegin = begin(seqV, Standard()) - _min(0, 1+upperDiagonal(band));
-//    TConstSeqVIterator seqVEnd = begin(seqV, Standard()) - _min(0, _max(-static_cast<int>(length(seqV)), lowerDiagonal(band)));
-//
-////    std::cout << "Begin Pos: " << seqVBegin - begin(seqV) << "\n";
-////    std::cout << "End Pos: " << seqVEnd - begin(seqV) << "\n";
-//
-//    // We have to distinguish two band sizes. Some which spans the whole matrix in between and thus who not.
-//    // This can be distinguished, if UpperDiagonal > length(seqV) + LowerDiagonal
-//
-//    // We start at the least at the first sequence or wherever the lower diagonal begins first.
-//    TConstSeqHIterator seqHIterBegin = begin(seqH, Standard()) + _max(0, _min(static_cast<int>(length(seqH) - 1), lowerDiagonal(band)));
-//    // TODO(rmaerker): Cehck if this assertion is correct.
-////    SEQAN_ASSERT_NEQ(seqHIterBegin, end(seqH, Standard()));  // The iterator never points to the end of the horizontal sequence.
-//
-//    // The horizontal initial phase ends after the upper diagonal but at most after the horizontal sequence, or there is no horizontal initialization phase.
-//    TConstSeqHIterator seqHIterEndColumnTop = begin(seqH, Standard()) + _min(static_cast<int>(length(seqH))-1, _max(0, upperDiagonal(band)));
-//
-//    // The middle band phase ends after the lower diagonal crosses the bottom of the alignment matrix or after the horizontal sequence if it is smaller.
-//    TConstSeqHIterator seqHIterEndColumnMiddle = begin(seqH, Standard()) + _min(static_cast<int>(length(seqH))-1, _max(0,static_cast<int>(length(seqV)) + lowerDiagonal(band)));
-//    // Swap the two iterators if we are in a band that spans over the full column.
-//    if (upperDiagonal(band) > static_cast<int>(length(seqV)) + lowerDiagonal(band))
-//        std::swap(seqHIterEndColumnTop, seqHIterEndColumnMiddle);
-//
-//    // The bottom band phase ends after the upper diagonal of the band crosses the bottom of the matrix or after the horizontal sequence if it is smaller.
-//    TConstSeqHIterator seqHIterEndColumnBottom = begin(seqH, Standard()) + _max(0, _min(static_cast<int>(length(seqH)),
-//                                                 upperDiagonal(band) + static_cast<int>(length(seqV))) -1);
-//
-////    std::cout << "seqHIterBegin Pos H: " << seqHIterBegin - begin(seqH) << "\n";
-////    std::cout << "seqHIterEndColumnTop Pos H: " << seqHIterEndColumnTop - begin(seqH) << "\n";
-////    std::cout << "seqHIterEndColumnMiddle Pos H: " << seqHIterEndColumnMiddle - begin(seqH) << "\n";
-////    std::cout << "seqHIterEndColumnBottom Pos H: " << seqHIterEndColumnBottom - begin(seqH) << "\n";
-////
-////    std::cout << "_activeColIterator Pos: " << dpScoreMatrixNavigator._activeColIterator - begin(*dpScoreMatrixNavigator._ptrDataContainer) << "\n";
-////    std::cout << "_prevColIterator Pos: " << dpScoreMatrixNavigator._prevColIterator - begin(*dpScoreMatrixNavigator._ptrDataContainer) << "\n";
-//
-//    // The Initial column can be PartialColumnTop which is given if the upper diagonal is >= 0,
-//    // otherwise it only can be PartialColumnMiddle or PartialColumnBottom depending where the lower diagonal is.
-//
-//    // Have to check for single initialization cells in InitialColumn and FinalColumn.
-//    if (seqHIterBegin == end(seqH)-1)
-//    {
-//        // Set the iterator to the begin of the track.
-//        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
-//        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
-//        // Only one cell
-//        _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-//                previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-//                previousCellVertical(dpScoreMatrixNavigator), value(seqHIterBegin), TSeqVValue(), scoringScheme,
-//                MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell(), TDPProfile());
-////      std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n";
-//      std::stringstream stream;
-//      stream << _scoreOfCell(value(dpScoreMatrixNavigator));
-//      testMatrix[length(seqH) * length(seqV)] = stream.str();
-//        // we might need to additionally track this point.
-//        if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop> >, FirstCell>::VALUE)
-//            _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//        return;
-//    }
-//    if (seqHIterEndColumnBottom == begin(seqH))
-//    {
-//        // Set the iterator to the begin of the track.
-//        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
-//        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
-//        // Only one cell
-//        _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-//                previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-//                previousCellVertical(dpScoreMatrixNavigator), TSeqHValue(), value(seqVBegin), scoringScheme,
-//                MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
-////      std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n";
-//      std::stringstream stream;
-//      stream << _scoreOfCell(value(dpScoreMatrixNavigator));
-//      testMatrix[length(seqH) * length(seqV)] = stream.str();
-//        // We might need to additionally track this point.
-//        if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom> >, LastCell>::VALUE)
-//            _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//        return;
-//    }
-//
-//    if (upperDiagonal(band) < 0)
-//    {
-//        ++seqVBegin;
-//        if (lowerDiagonal(band) > -static_cast<int>(length(seqV)))
-//          _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                  TSeqHValue(), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme,
-//                  MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), dpProfile, 0, seqVBegin - begin(seqV) + 1, testMatrix);
-//        else
-//          _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                  TSeqHValue(), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme,
-//                  MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), dpProfile, 0, seqVBegin - begin(seqV) + 1, testMatrix);
-//    }
-//    else if (lowerDiagonal(band) >= 0)
-//    {
-//        // Set the iterator to the begin of the track.
-//        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
-//        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
-//        // Should we not just compute the cell?
-//        _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-//                previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-//                previousCellVertical(dpScoreMatrixNavigator), value(seqHIterBegin), TSeqVValue(), scoringScheme,
-//                MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell(), TDPProfile());
-//        // we might need to additionally track this point.
-////      std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n";
-//      int col = lowerDiagonal(band);
-//      std::stringstream stream;
-//      stream << _scoreOfCell(value(dpScoreMatrixNavigator));
-//      testMatrix[col * (length(seqV) + 1)] = stream.str();
-//        if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop> >, FirstCell>::VALUE)
-//            _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//    }
-//    else  // Upper diagonal >= 0 and lower Diagonal < 0
-//        if (lowerDiagonal(band) <= -static_cast<int>(length(seqV)))  // The band is bounded by the top and bottom of the matrix.
-//          _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                  TSeqHValue(), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme,
-//                  MetaColumnDescriptor<DPInitialColumn, FullColumn>(), dpProfile, 0, 0, testMatrix);
-//        else   // The band is bounded by the top but not the bottom of the matrix.
-//          _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                  TSeqHValue(), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme,
-//                  MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), dpProfile, 0,0, testMatrix);
-//
-//
-//    // RECURSION
-//    TConstSeqHIterator seqHIter = seqHIterBegin;
-//    // Compute the first part of the band, where the band is bounded by the top but not by the bottom of the matrix.
-//    for (;seqHIter != seqHIterEndColumnTop; ++seqHIter)
-//    {
-////      std::cout << value(seqHIter) << ":\t";
-//        ++seqVEnd;
-//      _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//              value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme,
-//              MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), dpProfile, ((seqHIter - begin(seqH)) + 1)*(length(seqV) +1), 0, testMatrix);
-//    }
-//
-//    // Check whether the band spans over the full column or not at some point.
-//    if (upperDiagonal(band) > static_cast<int>(length(seqV)) + lowerDiagonal(band))
-//    {
-//        // Compute the second part of the band, where the band is bounded by the top and the bottom of the matrix.
-//        // We might want to track the current cell here, since this is the first cell that crosses the bottom.
-//        // TODO(rmaerker): We have to check if the initial column/ row can be tracked!!!
-//        if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, FullColumn> >, LastCell>::VALUE)
-//                _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//        for (;seqHIter != seqHIterEndColumnMiddle; ++seqHIter)
-//        {
-//          _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                  value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme,
-//                  MetaColumnDescriptor<DPInnerColumn, FullColumn>(), dpProfile, (seqHIter - begin(seqH) + 1) * (length(seqV) + 1), 0, testMatrix);
-//        }
-//    }
-//    else // Compute the second part of the band, where the band is not bounded by the top and bottom of the matrix
-//    {
-//        for (;seqHIter != seqHIterEndColumnMiddle; ++seqHIter)
-//        {
-//            ++seqVBegin;
-//            ++seqVEnd;
-//          _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                  value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme,
-//                  MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), dpProfile, (seqHIter - begin(seqH) +1) * (length(seqV)+1), seqVBegin - begin(seqV), testMatrix);
-//        }   // We might want to track the current cell here, since this is the first cell that crosses the bottom.
-//        if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom> >, LastCell>::VALUE)
-//        {
-//            // TODO(rmaerker): This is only a hot fix.
-//            if (lowerDiagonal(band) + length(seqV) < length(seqH))
-//                _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//        }
-//    }
-//    // Compute the third part of the band, where the band, is bounded by the bottom but not by the top of the matrix.
-//    for (;seqHIter != seqHIterEndColumnBottom; ++seqHIter)
-//    {
-//        ++seqVBegin;
-//      _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//              value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme,
-//              MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), dpProfile, (seqHIter - begin(seqH) + 1) * (length(seqV) + 1), seqVBegin - begin(seqV), testMatrix);
-//    }
-//
-//    // Where ends the last cell?
-//    if(seqHIter - begin(seqH) < static_cast<int>(length(seqH))-1)  // Case 1: The band ends before the final column is reached.
-//    {
-//        // Set the iterator to the begin of the track.
-//        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
-//        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
-//
-//        _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-//                previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-//                previousCellVertical(dpScoreMatrixNavigator), value(seqHIter), value(seqVBegin), scoringScheme,
-//                MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
-////      std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n";
-//      std::stringstream stream;
-//      stream << _scoreOfCell(value(dpScoreMatrixNavigator));
-//      testMatrix[(seqHIter - begin(seqH) + 1) * (length(seqV) + 1) + length(seqV)] = stream.str();
-//        // We might need to additionally track this point.
-//        if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom> >, LastCell>::VALUE)
-//            _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//    }
-//    else if(seqHIter == end(seqH)-1)  // Case 2: The band ends somewhere in the final column of the matrix.
-//    {
-//        if (upperDiagonal(band) == static_cast<int>(length(seqH))-static_cast<int>(length(seqV)))  // Case2a: The band ends in the last cell of the final column.  // He should be here....
-//        {
-//            // Set the iterator to the begin of the track.
-//            _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
-//            _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
-//
-//            _computeCell(scout, dpTraceMatrixNavigator, value(dpScoreMatrixNavigator),
-//                    previousCellDiagonal(dpScoreMatrixNavigator), previousCellHorizontal(dpScoreMatrixNavigator),
-//                    previousCellVertical(dpScoreMatrixNavigator), value(seqHIter), value(seqVBegin), scoringScheme,
-//                    MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell(), TDPProfile());
-////          std::cout << _scoreOfCell(value(dpScoreMatrixNavigator)) << "\n";
-//          std::stringstream stream;
-//          stream << _scoreOfCell(value(dpScoreMatrixNavigator));
-//          testMatrix[(length(seqH) * (length(seqV) + 1)) + length(seqV)] = stream.str();
-//            // we might need to additionally track this point.
-//            if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom> >, LastCell>::VALUE)
-//                _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//        }
-//        else  // Case2b: At least two cells intersect between the band and the matrix in the final column of the matrix.
-//        {
-//            if (upperDiagonal(band) >= static_cast<int>(length(seqH)))  // The band is bounded by the top of the matrix only or by the top and the bottom.
-//            {
-//                if (lowerDiagonal(band) + static_cast<int>(length(seqV)) > static_cast<int>(length(seqH))) // The band is bounded by the top of the matrix
-//                {
-//                    ++seqVEnd;
-//                  _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                          value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme,
-//                          MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), dpProfile, length(seqH) * (length(seqV) + 1), 0, testMatrix);
-//                }
-//                else  // The band is bounded by the top and the bottom of the matrix.
-//                {
-//                    if (lowerDiagonal(band) + static_cast<int>(length(seqV)) + 1 > static_cast<int>(length(seqH)) )
-//                    {
-//                        ++seqVEnd;
-//                      _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                              value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme,
-//                              MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), dpProfile, length(seqH) * (length(seqV) + 1), 0, testMatrix);
-//                        if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >, LastCell>::VALUE)
-//                            _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//                    }
-//                    else
-//                      _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                              value(seqHIter), TSeqVValue(), seqVBegin, seqVEnd, scoringScheme,
-//                              MetaColumnDescriptor<DPFinalColumn, FullColumn>(), dpProfile, length(seqH) * (length(seqV) +1), 0, testMatrix);
-//
-//                }
-//
-//            }
-//            else  // The band is bounded by bottom of matrix or completely unbounded.
-//            {
-//                ++seqVBegin;
-//                if (lowerDiagonal(band) + length(seqV) <= length(seqH)) // The band is bounded by the bottom of the matrix.
-//                {
-//                    if (lowerDiagonal(band) + length(seqV) == length(seqH))
-//                    {
-//                        ++seqVEnd;
-//                      _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                          value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme,
-//                          MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), dpProfile, length(seqH) * (length(seqV)+1), seqVBegin - begin(seqV), testMatrix);
-//                      if (TrackingEnabled_<DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom> >, LastCell>::VALUE)
-//                          _scoutBestScore(scout, _scoreOfCell(value(dpScoreMatrixNavigator)), dpTraceMatrixNavigator);
-//                    }
-//                    else
-//                    {
-//                      _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                          value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme,
-//                          MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), dpProfile, length(seqH) * (length(seqV) + 1), seqVBegin - begin(seqV), testMatrix);
-//                    }
-//                }
-//                else  // The band is unbounded by the matrix.
-//                {
-//                    ++seqVEnd;
-//                  _computeTrack(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator,
-//                      value(seqHIter), value(seqVBegin-1), seqVBegin, seqVEnd, scoringScheme,
-//                      MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), dpProfile, length(seqH) * (length(seqV)+1), seqVBegin - begin(seqV), testMatrix);
-//                }
-//
-//            }
-//        }
-//    }
-//
-//    for (unsigned i = 0; i <= length(seqV); ++i)
-//    {
-//      for (unsigned j = 0; j <= length(seqH); ++j)
-//      {
-//          unsigned pos = j * (length(seqV) + 1) + i;
-//          //if (!testMatrix[pos].empty())
-//              std::cout << testMatrix[pos] << "\t" << std::flush;
-//      }
-//      std::cout << std::endl;
-//    }
-//
-//}
-
 // ----------------------------------------------------------------------------
 // Function _computeHammingDistance()
 // ----------------------------------------------------------------------------
 
 // Computes the Hamming-Distance if the band-size is 1.
-template <typename TDPScout, typename TDPScoreMatrixNavigator, typename TDPTraceMatrixNavigator, typename TSequenceH,
-          typename TSequenceV, typename TScoringScheme, typename TBand, typename TAlignmentAlgo, typename TGapCosts,
-          typename TTraceFlag>
+template <typename TDPScout,
+          typename TDPScoreMatrixNavigator,
+          typename TDPTraceMatrixNavigator,
+          typename TSequenceH,
+          typename TSequenceV,
+          typename TScoringScheme,
+          typename TBand,
+          typename TAlignmentAlgo, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
 inline void
 _computeHammingDistance(TDPScout & scout,
                         TDPScoreMatrixNavigator & dpScoreMatrixNavigator,
@@ -1180,7 +971,7 @@ _computeHammingDistance(TDPScout & scout,
                         TSequenceV const & seqV,
                         TScoringScheme const & scoringScheme,
                         TBand const & band,
-                        DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag> const &)
+                        DPProfile_<TAlignmentAlgo, TGapCosts, TTraceFlag, TExecPolicy> const &)
 {
     typedef typename MakeSigned<typename Size<TSequenceH const>::Type>::Type TSignedSizeSeqH;
     typedef typename MakeSigned<typename Size<TSequenceV const>::Type>::Type TSignedSizeSeqV;
@@ -1202,8 +993,9 @@ _computeHammingDistance(TDPScout & scout,
     TConstSeqVIterator itV = begin(seqV, Rooted()) + _max(0, _min(seqVlength - 1, -lowerDiagonal(band)));
     TConstSeqVIterator itVEnd = begin(seqV, Rooted()) + _min(seqVlength - 1, lowerDiagonal(band) + seqHlength);
 
+    TDPCell dummy;
     assignValue(dpTraceMatrixNavigator,
-                _computeScore(value(dpScoreMatrixNavigator), TDPCell(), TDPCell(), TDPCell(),
+                _computeScore(value(dpScoreMatrixNavigator), dummy, dummy, dummy,
                               sequenceEntryForScore(scoringScheme, seqH, position(itH)),
                               sequenceEntryForScore(scoringScheme, seqV, position(itV)),
                               scoringScheme, RecursionDirectionZero(), TDPProfile()));
@@ -1253,7 +1045,7 @@ _computeHammingDistance(TDPScout & scout,
         _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
         _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
         assignValue(dpTraceMatrixNavigator,
-                    _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, TDPCell(), TDPCell(),
+                    _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, dummy, dummy,
                                   sequenceEntryForScore(scoringScheme, seqH, position(itH)),
                                   sequenceEntryForScore(scoringScheme, seqV, position(itV)),
                                   scoringScheme, RecursionDirectionDiagonal(), TDPProfile()));
@@ -1272,7 +1064,7 @@ _computeHammingDistance(TDPScout & scout,
     _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
 
     assignValue(dpTraceMatrixNavigator,
-                _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, TDPCell(), TDPCell(),
+                _computeScore(value(dpScoreMatrixNavigator), prevDiagonal, dummy, dummy,
                               sequenceEntryForScore(scoringScheme, seqH, position(itH)),
                               sequenceEntryForScore(scoringScheme, seqV, position(itV)),
                               scoringScheme, RecursionDirectionDiagonal(), TDPProfile()));
@@ -1295,6 +1087,29 @@ _computeHammingDistance(TDPScout & scout,
 }
 
 // ----------------------------------------------------------------------------
+// Function _printScoreMatrix()
+// ----------------------------------------------------------------------------
+
+template <typename TTraceMatrix>
+void _printScoreMatrix(TTraceMatrix & scoreMatrix)
+{
+    typedef typename Size<TTraceMatrix>::Type TSize;
+    TSize dimH = length(scoreMatrix, +DPMatrixDimension_::HORIZONTAL);
+    TSize dimV = length(scoreMatrix, +DPMatrixDimension_::VERTICAL);
+
+    for (unsigned row = 0; row < dimV; ++row)
+    {
+        for (unsigned column = 0; column < dimH; ++column)
+            if (_scoreOfCell(value(scoreMatrix, row + column * dimV)) <= DPCellDefaultInfinity<DPCell_<int, LinearGaps>>::VALUE)
+                std::cout << "-∞\t";
+            else
+                std::cout << _scoreOfCell(value(scoreMatrix, row + column * dimV)) << "\t";
+        std::cout << std::endl;
+    }
+    std::cout << std::endl;
+}
+
+// ----------------------------------------------------------------------------
 // Function _printTracebackMatrix()
 // ----------------------------------------------------------------------------
 
@@ -1374,11 +1189,15 @@ inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, void)
 _correctTraceValue(TTraceNavigator & traceNavigator,
                    DPScout_<DPCell_<TScoreValue, AffineGaps>, TDPScoutSpec>  const & dpScout)
 {
-    _setToPosition(traceNavigator, maxHostPosition(dpScout));
-    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;
+    using TMaskType = typename SimdMaskVector<TScoreValue>::Type;
+    _setToPosition(traceNavigator, toGlobalPosition(traceNavigator,
+                                                    maxHostCoordinate(dpScout, +DPMatrixDimension_::HORIZONTAL),
+                                                    maxHostCoordinate(dpScout, +DPMatrixDimension_::VERTICAL)));
+    TMaskType flag = createVector<TMaskType>(0);
+    assignValue(flag, dpScout._simdLane, -1);
+    auto cmpV = cmpEq(_verticalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)) & flag;
+    auto cmpH = cmpEq(_horizontalScoreOfCell(dpScout._maxScore), _scoreOfCell(dpScout._maxScore)) & flag;
+
     value(traceNavigator) = blend(value(traceNavigator),
                                   value(traceNavigator) & ~TraceBitMap_<TScoreValue>::DIAGONAL,
                                   cmpV | cmpH);
@@ -1413,11 +1232,13 @@ inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, void)
 _correctTraceValue(TTraceNavigator & traceNavigator,
                    DPScout_<DPCell_<TScoreValue, DynamicGaps>, TDPScoutSpec>  const & dpScout)
 {
+    using TMaskType = typename SimdMaskVector<TScoreValue>::Type;
+
     _setToPosition(traceNavigator, maxHostPosition(dpScout));
-    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;
+    TMaskType flag = createVector<TMaskType>(0);
+    assignValue(flag, dpScout._simdLane, -1);
+    auto cmpV = isGapExtension(dpScout._maxScore, DynamicGapExtensionVertical()) & flag;
+    auto cmpH = isGapExtension(dpScout._maxScore, DynamicGapExtensionHorizontal()) & flag;
     value(traceNavigator) = blend(value(traceNavigator),
                                   value(traceNavigator) & ~TraceBitMap_<TScoreValue>::DIAGONAL,
                                   cmpV | cmpH);
@@ -1439,7 +1260,7 @@ template <typename TTraceTarget,
           typename TSeqH,
           typename TSeqV,
           typename TBandSwitch,
-          typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag>
+          typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy>
 inline SEQAN_FUNC_ENABLE_IF(Not<IsTracebackEnabled_<TTraceFlag> >, TScoreValue)
 _finishAlignment(TTraceTarget & /*traceSegments*/,
                  TTraceMatNavigator & /*dpTraceMatrixNavigator*/,
@@ -1447,7 +1268,7 @@ _finishAlignment(TTraceTarget & /*traceSegments*/,
                  TSeqH const & /*seqH*/,
                  TSeqV const & /*seqV*/,
                  DPBandConfig<TBandSwitch> const & /*band*/,
-                 DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag> const & /*dpProfile*/)
+                 DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & /*dpProfile*/)
 {
     return maxScore(dpScout);
 }
@@ -1458,7 +1279,7 @@ template <typename TTraceTarget,
           typename TSeqH,
           typename TSeqV,
           typename TBandSwitch,
-          typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag>
+          typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy>
 inline SEQAN_FUNC_ENABLE_IF(And<Is<SimdVectorConcept<TScoreValue> >, IsTracebackEnabled_<TTraceFlag> >, TScoreValue)
 _finishAlignment(TTraceTarget & traceSegments,
                  TTraceMatNavigator & dpTraceMatrixNavigator,
@@ -1466,7 +1287,7 @@ _finishAlignment(TTraceTarget & traceSegments,
                  TSeqH const & seqH,
                  TSeqV const & seqV,
                  DPBandConfig<TBandSwitch> const & band,
-                 DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag> const & dpProfile)
+                 DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & dpProfile)
 {
     typedef typename Size<TTraceTarget>::Type TSize;
 
@@ -1479,7 +1300,11 @@ _finishAlignment(TTraceTarget & traceSegments,
         {
             _correctTraceValue(dpTraceMatrixNavigator, scout);
         }
-        _computeTraceback(traceSegments[i], dpTraceMatrixNavigator, scout, _hostLengthH(scout, seqH),
+        _computeTraceback(traceSegments[i], dpTraceMatrixNavigator,
+                          toGlobalPosition(dpTraceMatrixNavigator,
+                                           maxHostCoordinate(scout, +DPMatrixDimension_::HORIZONTAL),
+                                           maxHostCoordinate(scout, +DPMatrixDimension_::VERTICAL)),
+                          _hostLengthH(scout, seqH),
                           _hostLengthV(scout, seqV), band, dpProfile);
     }
     return maxScore(scout);
@@ -1491,7 +1316,7 @@ template <typename TTraceTarget,
           typename TSeqH,
           typename TSeqV,
           typename TBandSwitch,
-          typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag>
+          typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy>
 inline SEQAN_FUNC_ENABLE_IF(And<Not<Is<SimdVectorConcept<TScoreValue> > >, IsTracebackEnabled_<TTraceFlag> >, TScoreValue)
 _finishAlignment(TTraceTarget & traceSegments,
                  TTraceMatNavigator & dpTraceMatrixNavigator,
@@ -1499,7 +1324,7 @@ _finishAlignment(TTraceTarget & traceSegments,
                  TSeqH const & seqH,
                  TSeqV const & seqV,
                  DPBandConfig<TBandSwitch> const & band,
-                 DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag> const & dpProfile)
+                 DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & dpProfile)
 {
     if (IsSingleTrace_<TTraceFlag>::VALUE)
         _correctTraceValue(dpTraceMatrixNavigator, dpScout);
@@ -1512,35 +1337,42 @@ _finishAlignment(TTraceTarget & traceSegments,
 // Function _computeAligmnment()
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TGapScheme, typename TTraceTarget, typename TScoutState, typename TSequenceH, typename TSequenceV,
-          typename TScoreScheme, typename TBandSwitch, typename TAlignmentAlgorithm, typename TTraceFlag>
+template <typename TDPScoreValue, typename TTraceValue, typename TScoreMatHost, typename TTraceMatHost,
+          typename TTraceTarget,
+          typename TScoutState,
+          typename TSequenceH,
+          typename TSequenceV,
+          typename TScoreScheme,
+          typename TBandSwitch,
+          typename TAlignmentAlgorithm, typename TGapScheme, typename TTraceFlag, typename TExecPolicy>
 inline typename Value<TScoreScheme>::Type
-_computeAlignment(DPContext<TScoreValue, TGapScheme> & dpContext,
+_computeAlignment(DPContext<TDPScoreValue, TTraceValue, TScoreMatHost, TTraceMatHost> & dpContext,
                   TTraceTarget & traceSegments,
                   TScoutState & scoutState,
                   TSequenceH const & seqH,
                   TSequenceV const & seqV,
                   TScoreScheme const & scoreScheme,
                   DPBandConfig<TBandSwitch> const & band,
-                  DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag> const & dpProfile)
+                  DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & dpProfile)
 {
-    typedef typename GetDPScoreMatrix<DPContext<TScoreValue, TGapScheme> >::Type TDPScoreMatrixHost;
-    typedef typename Value<TDPScoreMatrixHost>::Type TDPScoreValue;
-
-    typedef typename GetDPTraceMatrix<DPContext<TScoreValue, TGapScheme> >::Type TDPTraceMatrixHost;
-    typedef typename Value<TDPTraceMatrixHost>::Type TTraceValue;
 
     typedef typename DefaultScoreMatrixSpec_<TAlignmentAlgorithm>::Type TScoreMatrixSpec;
 
-    typedef DPMatrix_<TDPScoreValue, TScoreMatrixSpec> TDPScoreMatrix;
-    typedef DPMatrix_<TTraceValue, FullDPMatrix> TDPTraceMatrix;
+    typedef DPMatrix_<TDPScoreValue, TScoreMatrixSpec, TScoreMatHost>   TDPScoreMatrix;
+    typedef DPMatrix_<TTraceValue, FullDPMatrix, TTraceMatHost>         TDPTraceMatrix;
+
+    using TNavigationSpec = std::conditional_t<std::is_same<TBandSwitch, BandOff>::value,
+                                               NavigateColumnWise,
+                                               NavigateColumnWiseBanded>;
 
-    typedef DPMatrixNavigator_<TDPScoreMatrix, DPScoreMatrix, NavigateColumnWise> TDPScoreMatrixNavigator;
-    typedef DPMatrixNavigator_<TDPTraceMatrix, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> TDPTraceMatrixNavigator;
+    typedef DPMatrixNavigator_<TDPScoreMatrix, DPScoreMatrix, TNavigationSpec> TDPScoreMatrixNavigator;
+    typedef DPMatrixNavigator_<TDPTraceMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> TDPTraceMatrixNavigator;
 
     typedef typename ScoutSpecForAlignmentAlgorithm_<TAlignmentAlgorithm, TScoutState>::Type TDPScoutSpec;
     typedef DPScout_<TDPScoreValue, TDPScoutSpec> TDPScout;
 
+    typedef typename Value<TScoreScheme>::Type TScoreValue;
+
     // Check if current dp settings are valid. If not return infinity value for dp score value.
     if (!_isValidDPSettings(seqH, seqV, band, dpProfile))
         return createVector<TScoreValue>(std::numeric_limits<typename Value<TScoreValue>::Type>::min());  // NOTE(rrahn): In case of non-simd version, createVector returns just a scalar.
@@ -1552,7 +1384,7 @@ _computeAlignment(DPContext<TScoreValue, TGapScheme> & dpContext,
     setLength(dpScoreMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1 - std::max(0, lowerDiagonal(band)));
     setLength(dpTraceMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1 - std::max(0, lowerDiagonal(band)));
 
-    if (IsSameType<TBandSwitch, BandOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TBandSwitch, BandOff>::VALUE)
     {
         setLength(dpScoreMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1);
         setLength(dpTraceMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1);
@@ -1573,11 +1405,8 @@ _computeAlignment(DPContext<TScoreValue, TGapScheme> & dpContext,
     if (IsTracebackEnabled_<TTraceFlag>::VALUE)
         resize(dpTraceMatrix);
 
-    TDPScoreMatrixNavigator dpScoreMatrixNavigator;
-    TDPTraceMatrixNavigator dpTraceMatrixNavigator;
-
-    _init(dpScoreMatrixNavigator, dpScoreMatrix, band);
-    _init(dpTraceMatrixNavigator, dpTraceMatrix, band);
+    TDPScoreMatrixNavigator dpScoreMatrixNavigator{dpScoreMatrix, band};
+    TDPTraceMatrixNavigator dpTraceMatrixNavigator{dpTraceMatrix, band};
 
     TDPScout dpScout(scoutState);
 #if SEQAN_ALIGN_SIMD_PROFILE
@@ -1585,13 +1414,9 @@ _computeAlignment(DPContext<TScoreValue, TGapScheme> & dpContext,
     timer = sysTime();
 #endif
     // Execute the alignment.
-    if (!_isBandEnabled(band))
-        _computeUnbandedAlignment(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme, dpProfile);
-    else if (upperDiagonal(band) == lowerDiagonal(band))
-        _computeHammingDistance(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme, band, dpProfile);
-    else
-        _computeBandedAlignment(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme,
-                                band, dpProfile);
+    _computeAlignmentImpl(dpScout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV, scoreScheme, band,
+                          dpProfile, TNavigationSpec{});
+
 #if SEQAN_ALIGN_SIMD_PROFILE
     profile.alignTimer += sysTime() - timer;
     timer = sysTime();
diff --git a/include/seqan/align/dp_align_simd_helper.h b/include/seqan/align/dp_align_simd_helper.h
index e24502d..1d56f86 100644
--- a/include/seqan/align/dp_align_simd_helper.h
+++ b/include/seqan/align/dp_align_simd_helper.h
@@ -127,70 +127,46 @@ _precomputeScoreMatrixOffset(TSeqValue const & seqVal,
 // Function _prepareAndRunSimdAlignment()
 // ----------------------------------------------------------------------------
 
-template <typename TResult,
-          typename TTraces,
+template <typename TStringSimdH,
+          typename TStringSimdV,
           typename TSequencesH,
-          typename TSequencesV,
-          typename TScore,
-          typename TAlgo, typename TBand, typename TFreeEndGaps, typename TTraceback,
-          typename TGapModel>
+          typename TSequencesV>
 inline void
-_prepareAndRunSimdAlignment(TResult & results,
-                            TTraces & traces,
-                            TSequencesH const & seqH,
-                            TSequencesV const & seqV,
-                            TScore const & scoringScheme,
-                            AlignConfig2<TAlgo, TBand, TFreeEndGaps, TTraceback> const & alignConfig,
-                            TGapModel const & /*gapModel*/,
-                            SimdAlignEqualLength const & /*tag*/)
+_prepareSimdAlignment(TStringSimdH & stringSimdH,
+                      TStringSimdV & stringSimdV,
+                      TSequencesH const & seqH,
+                      TSequencesV const & seqV,
+                      DPScoutState_<SimdAlignEqualLength> const & /*unused*/)
 {
-    String<TResult, Alloc<OverAligned> > stringSimdH;
-    String<TResult, Alloc<OverAligned> > stringSimdV;
-
     resize(stringSimdH, length(seqH[0]));
     resize(stringSimdV, length(seqV[0]));
     _createSimdRepImpl(stringSimdH, seqH);
     _createSimdRepImpl(stringSimdV, seqV);
-
-    DPScoutState_<SimdAlignEqualLength> state;
-    results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel());
 }
 
-template <typename TResult,
-          typename TTraces,
+template <typename TStringSimdH,
+          typename TStringSimdV,
           typename TSequencesH,
           typename TSequencesV,
-          typename TScore,
-          typename TAlgo, typename TBand, typename TFreeEndGaps, typename TTraceback,
-          typename TGapModel,
           typename TTraits>
 inline void
-_prepareAndRunSimdAlignment(TResult & results,
-                            TTraces & traces,
-                            TSequencesH const & seqH,
-                            TSequencesV const & seqV,
-                            TScore const & scoringScheme,
-                            AlignConfig2<TAlgo, TBand, TFreeEndGaps, TTraceback> const & alignConfig,
-                            TGapModel const & /*gapModel*/,
-                            SimdAlignVariableLength<TTraits> const /*tag*/)
+_prepareSimdAlignment(TStringSimdH & stringSimdH,
+                      TStringSimdV & stringSimdV,
+                      TSequencesH const & seqH,
+                      TSequencesV const & seqV,
+                      String<size_t> & lengthsH,
+                      String<size_t> & lengthsV,
+                      DPScoutState_<SimdAlignVariableLength<TTraits> > & state)
 {
     SEQAN_ASSERT_EQ(length(seqH), length(seqV));
-    SEQAN_ASSERT_EQ(static_cast<decltype(length(seqH))>(LENGTH<TResult>::VALUE), length(seqH));
+    SEQAN_ASSERT_EQ(static_cast<decltype(length(seqH))>(LENGTH<typename Value<TStringSimdH>::Type>::VALUE), length(seqH));
 
-    using TSimdValueType = typename Value<TResult>::Type;
+    using TSimdVector = typename TTraits::TSimdVector;
+    using TSimdValueType = typename Value<TSimdVector>::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;
-
-    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), Exact{});
     resize(lengthsV, length(seqV), Exact{});
 
@@ -242,8 +218,6 @@ _prepareAndRunSimdAlignment(TResult & results,
     resize(stringSimdV, maxV);
     _createSimdRepImpl(stringSimdH, paddedH);
     _createSimdRepImpl(stringSimdV, paddedV);
-
-    results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel());
 }
 
 template <typename TResult,
@@ -269,33 +243,56 @@ _prepareAndRunSimdAlignment(TResult & results,
                                      [seqLengthH, seqLengthV](auto param)
                                      {
                                          return (length(std::get<0>(param)) == seqLengthH) &&
-                                         (length(std::get<1>(param)) == seqLengthV);
+                                                (length(std::get<1>(param)) == seqLengthV);
                                      });
+
+    String<TResult, Alloc<OverAligned> > stringSimdH;
+    String<TResult, Alloc<OverAligned> > stringSimdV;
     if(allSameLength)
-        _prepareAndRunSimdAlignment(results, traces, seqH, seqV, scoringScheme, alignConfig, TGapModel(),
-                                    SimdAlignEqualLength());
+    {
+        DPScoutState_<SimdAlignEqualLength> state;
+        _prepareSimdAlignment(stringSimdH, stringSimdV, seqH, seqV, state);
+        results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel());
+    }
     else
-        _prepareAndRunSimdAlignment(results, traces, seqH, seqV, scoringScheme, alignConfig, TGapModel(),
-                                    SimdAlignVariableLength<Nothing>());
+    {
+        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;
+        _prepareSimdAlignment(stringSimdH, stringSimdV, seqH, seqV, lengthsH, lengthsV, state);
+
+        results = _setUpAndRunAlignment(traces, state, stringSimdH, stringSimdV, scoringScheme, alignConfig, TGapModel());
+    }
 }
 
 // ----------------------------------------------------------------------------
 // Function _alignWrapperSimd(); Score; StringSet vs. StringSet
 // ----------------------------------------------------------------------------
 
-template <typename TString1, typename TSpec1,
-          typename TString2, typename TSpec2,
+template <typename TSetH,
+          typename TSetV,
           typename TScoreValue, typename TScoreSpec,
           typename TAlignConfig,
-          typename TGapModel>
+          typename TGapModel,
+          std::enable_if_t<And<And<Is<ContainerConcept<TSetH>>,
+                                   Is<ContainerConcept<typename Value<TSetH>::Type>>>,
+                               And<Is<ContainerConcept<TSetV>>,
+                                   Is<ContainerConcept<typename Value<TSetV>::Type>>>
+                               >::VALUE,
+                          int> = 0>
 inline auto
-_alignWrapperSimd(StringSet<TString1, TSpec1> const & stringsH,
-                  StringSet<TString2, TSpec2> const & stringsV,
+_alignWrapperSimd(TSetH const & stringsH,
+                  TSetV const & stringsV,
                   Score<TScoreValue, TScoreSpec> const & scoringScheme,
                   TAlignConfig const & config,
                   TGapModel const & /*gaps*/)
 {
-    typedef typename SimdVector<int16_t>::Type TSimdAlign;
+    typedef typename SimdVector<TScoreValue>::Type TSimdAlign;
 
     unsigned const numAlignments = length(stringsV);
     unsigned const sizeBatch = LENGTH<TSimdAlign>::VALUE;
@@ -314,8 +311,8 @@ _alignWrapperSimd(StringSet<TString1, TSpec1> const & stringsH,
         TSimdAlign resultsBatch;
         if (SEQAN_UNLIKELY(numAlignments < pos + sizeBatch))
         {
-            StringSet<TString1, Dependent<> > depSetH;
-            StringSet<TString2, Dependent<> > depSetV;
+            StringSet<std::remove_const_t<typename Value<TSetH>::Type>, Dependent<> > depSetH;
+            StringSet<std::remove_const_t<typename Value<TSetV>::Type>, Dependent<> > depSetV;
             for (unsigned i = pos; i < fullSize; ++i)
             {
                 if (i >= numAlignments)
@@ -353,19 +350,25 @@ _alignWrapperSimd(StringSet<TString1, TSpec1> const & stringsH,
 // Function _alignWrapperSimd(); Score; String vs. StringSet
 // ----------------------------------------------------------------------------
 
-template <typename TString1,
-          typename TString2, typename TSpec,
+template <typename TSeqH,
+          typename TSetV,
           typename TScoreValue, typename TScoreSpec,
           typename TAlignConfig,
-          typename TGapModel>
+          typename TGapModel,
+          std::enable_if_t<And<And<Is<ContainerConcept<TSeqH>>,
+                                   Not<Is<ContainerConcept<typename Value<TSeqH>::Type>>>>,
+                               And<Is<ContainerConcept<TSetV>>,
+                                   Is<ContainerConcept<typename Value<TSetV>::Type>>>
+                              >::VALUE,
+                           int> = 0>
 inline auto
-_alignWrapperSimd(TString1 const & stringH,
-                  StringSet<TString2, TSpec> const & stringsV,
+_alignWrapperSimd(TSeqH const & stringH,
+                  TSetV const & stringsV,
                   Score<TScoreValue, TScoreSpec> const & scoringScheme,
                   TAlignConfig const & config,
                   TGapModel const & /*gaps*/)
 {
-    typedef typename SimdVector<int16_t>::Type TSimdAlign;
+    typedef typename SimdVector<TScoreValue>::Type TSimdAlign;
 
     unsigned const numAlignments = length(stringsV);
     unsigned const sizeBatch = LENGTH<TSimdAlign>::VALUE;
@@ -375,7 +378,7 @@ _alignWrapperSimd(TString1 const & stringH,
     resize(results, numAlignments);
 
     // Prepare strings.
-    StringSet<TString1, Dependent<> > setH;
+    StringSet<TSeqH, Dependent<> > setH;
     for (auto i = 0u; i < sizeBatch; ++i)
         appendValue(setH, stringH);
 
@@ -389,7 +392,7 @@ _alignWrapperSimd(TString1 const & stringH,
         TSimdAlign resultsBatch;
         if (SEQAN_UNLIKELY(numAlignments < pos + sizeBatch))
         {
-            StringSet<TString2, Dependent<> > depSetV;
+            StringSet<std::remove_const_t<typename Value<TSetV>::Type>, Dependent<> > depSetV;
             for (unsigned i = pos; i < fullSize; ++i)
             {
                 if (i >= numAlignments)
@@ -417,25 +420,31 @@ _alignWrapperSimd(TString1 const & stringH,
 // Function _alignWrapperSimd(); Gaps
 // ----------------------------------------------------------------------------
 
-template <typename TSequenceH, typename TGapsSpecH, typename TSetSpecH,
-          typename TSequenceV, typename TGapsSpecV, typename TSetSpecV,
+template <typename TSetH,
+          typename TSetV,
           typename TScoreValue, typename TScoreSpec,
           typename TAlignConfig,
-          typename TGapModel>
+          typename TGapModel,
+          std::enable_if_t<And<And<Is<ContainerConcept<TSetH>>,
+                                   Is<AlignedSequenceConcept<typename Value<TSetH>::Type>>>,
+                               And<Is<ContainerConcept<TSetV>>,
+                                   Is<AlignedSequenceConcept<typename Value<TSetV>::Type>>>
+                              >::VALUE,
+                          int> = 0>
 inline auto
-_alignWrapperSimd(StringSet<Gaps<TSequenceH, TGapsSpecH>, TSetSpecH> & gapSeqSetH,
-                  StringSet<Gaps<TSequenceV, TGapsSpecV>, TSetSpecV> & gapSeqSetV,
+_alignWrapperSimd(TSetH & gapSeqSetH,
+                  TSetV & gapSeqSetV,
                   Score<TScoreValue, TScoreSpec> const & scoringScheme,
                   TAlignConfig const & config,
                   TGapModel const & /*gaps*/)
 {
-    typedef Gaps<TSequenceH, TGapsSpecH>                                TGapSequenceH;
-    typedef Gaps<TSequenceV, TGapsSpecV>                                TGapSequenceV;
+    typedef typename Value<TSetH>::Type                                 TGapSequenceH;
+    typedef typename Value<TSetV>::Type                                 TGapSequenceV;
     typedef typename Size<TGapSequenceH>::Type                          TSize;
     typedef typename Position<TGapSequenceH>::Type                      TPosition;
     typedef TraceSegment_<TPosition, TSize>                             TTraceSegment;
 
-    typedef typename SimdVector<int16_t>::Type                          TSimdAlign;
+    typedef typename SimdVector<TScoreValue>::Type                      TSimdAlign;
 
 #if SEQAN_ALIGN_SIMD_PROFILE
     timer = sysTime();
@@ -452,8 +461,8 @@ _alignWrapperSimd(StringSet<Gaps<TSequenceH, TGapsSpecH>, TSetSpecH> & gapSeqSet
     Score<TSimdAlign, ScoreSimdWrapper<Score<TScoreValue, TScoreSpec> > > simdScoringScheme(scoringScheme);
 
     // Prepare string sets with sequences.
-    StringSet<typename Source<TGapSequenceH>::Type, Dependent<> > depSetH;
-    StringSet<typename Source<TGapSequenceV>::Type, Dependent<> > depSetV;
+    StringSet<std::remove_const_t<typename Source<TGapSequenceH>::Type>, Dependent<> > depSetH;
+    StringSet<std::remove_const_t<typename Source<TGapSequenceV>::Type>, Dependent<> > depSetV;
     reserve(depSetH, fullSize);
     reserve(depSetV, fullSize);
     for (unsigned i = 0; i < fullSize; ++i)
diff --git a/include/seqan/align/dp_cell.h b/include/seqan/align/dp_cell.h
index ee3c5d5..01e62a3 100644
--- a/include/seqan/align/dp_cell.h
+++ b/include/seqan/align/dp_cell.h
@@ -50,6 +50,12 @@ namespace seqan {
 // Tags, Classes, Enums
 // ============================================================================
 
+struct DynamicGapExtensionHorizontal_;
+typedef Tag<DynamicGapExtensionHorizontal_> DynamicGapExtensionHorizontal;
+
+struct DynamicGapExtensionVertical_;
+typedef Tag<DynamicGapExtensionVertical_> DynamicGapExtensionVertical;
+
 // ----------------------------------------------------------------------------
 // Class DPCell_
 // ----------------------------------------------------------------------------
@@ -66,6 +72,21 @@ class DPCell_;
 // ============================================================================
 
 // ----------------------------------------------------------------------------
+// Metafunction Spec
+// ----------------------------------------------------------------------------
+
+template <typename TScoreValue, typename TGapCostFunction>
+struct Spec<DPCell_<TScoreValue, TGapCostFunction> >
+{
+    typedef TGapCostFunction Type;
+};
+
+template <typename TScoreValue, typename TGapCostFunction>
+struct Spec<DPCell_<TScoreValue, TGapCostFunction> const> :
+    Spec<DPCell_<TScoreValue, TGapCostFunction> >
+{};
+
+// ----------------------------------------------------------------------------
 // Metafunction Value
 // ----------------------------------------------------------------------------
 
@@ -177,9 +198,16 @@ _setScoreOfCell(DPCell_<TScoreValue, TGapCosts> & dpCell, TScoreValue const & ne
     dpCell._score = newScore;
 }
 
-template <typename TScoreValue, typename TGapCosts>
+template <typename TScoreValue, typename TGapCosts, typename TMask>
 inline void
-_setScoreOfCell(DPCell_<TScoreValue, TGapCosts> & dpCell, TScoreValue const & newScore, TScoreValue const & mask)
+_setScoreOfCell(DPCell_<TScoreValue, TGapCosts> & dpCell, TScoreValue const & newScore)
+{
+    dpCell._score = newScore;
+}
+
+template <typename TScoreValue, typename TGapCosts, typename TMask>
+inline void
+_setScoreOfCell(DPCell_<TScoreValue, TGapCosts> & dpCell, TScoreValue const & newScore, TMask const & mask)
 {
     dpCell._score = blend(dpCell._score, newScore, mask);
 }
@@ -215,9 +243,9 @@ _setVerticalScoreOfCell(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TScoreValue
     // no-op
 }
 
-template <typename TScoreValue, typename TGapSpec>
+template <typename TScoreValue, typename TGapSpec, typename TMask>
 inline void
-_setVerticalScoreOfCell(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TScoreValue const & /*newVerticalScore*/, TScoreValue const & /*mask*/)
+_setVerticalScoreOfCell(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TScoreValue const & /*newVerticalScore*/, TMask const & /*mask*/)
 {
     // no-op
 }
@@ -253,9 +281,9 @@ _setHorizontalScoreOfCell(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TScoreVal
     // no-op
 }
 
-template <typename TScoreValue, typename TGapSpec>
+template <typename TScoreValue, typename TGapSpec, typename TMask>
 inline void
-_setHorizontalScoreOfCell(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TScoreValue const & /*newHorizontalScore*/, TScoreValue const & /*mask*/)
+_setHorizontalScoreOfCell(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TScoreValue const & /*newHorizontalScore*/, TMask const & /*mask*/)
 {
     // no-op
 }
@@ -271,13 +299,79 @@ setGapExtension(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TF1 , TF2)
     // no-op
 }
 
-template <typename TScoreValue, typename TGapSpec, typename TF1, typename TF2>
+template <typename TScoreValue, typename TGapSpec, typename TF1, typename TF2, typename TMask>
 inline void
-setGapExtension(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TF1 , TF2, TScoreValue)
+setGapExtension(DPCell_<TScoreValue, TGapSpec> & /*dpCell*/, TF1 , TF2, TMask)
 {
     // no-op
 }
 
+template <typename TTarget, typename TScoreValue, typename TGapSpec>
+inline void
+write(TTarget & target, DPCell_<TScoreValue, TGapSpec> const & cell)
+{
+    write(target, _scoreOfCell(cell));
+}
+
+// ----------------------------------------------------------------------------
+// Function isGapExtension()
+// ----------------------------------------------------------------------------
+
+template <typename TScoreValue, typename TGapSpec,
+          typename TSpec>
+inline bool
+isGapExtension(DPCell_<TScoreValue, TGapSpec> const & /*cell*/,
+               TSpec const & /*spec*/)
+{
+    return false;
+}
+
+// ----------------------------------------------------------------------------
+// Function operator==()
+// ----------------------------------------------------------------------------
+
+template <typename TScoreValue, typename TGapCosts>
+inline bool operator==(DPCell_<TScoreValue, TGapCosts> const & lhs,
+                       DPCell_<TScoreValue, TGapCosts> const & rhs)
+{
+    return _scoreOfCell(lhs) == _scoreOfCell(rhs) &&
+           _horizontalScoreOfCell(lhs) == _horizontalScoreOfCell(rhs) &&
+           _verticalScoreOfCell(lhs) == _verticalScoreOfCell(rhs);
+}
+
+// ----------------------------------------------------------------------------
+// Function operator!=()
+// ----------------------------------------------------------------------------
+
+template <typename TScoreValue, typename TGapCosts>
+inline bool operator!=(DPCell_<TScoreValue, TGapCosts> const & lhs,
+                       DPCell_<TScoreValue, TGapCosts> const & rhs)
+{
+    return !(lhs == rhs);
+}
+
+// ----------------------------------------------------------------------------
+// Function operator<<()
+// ----------------------------------------------------------------------------
+
+template <typename TStream,
+          typename TScoreValue, typename TGapCosts>
+inline TStream& operator<<(TStream & stream,
+                           DPCell_<TScoreValue, TGapCosts> const & cell)
+{
+    stream << "M: " << _scoreOfCell(cell);
+    if (std::is_same<TGapCosts, AffineGaps>::value)
+    {
+        stream << " <H: " << _horizontalScoreOfCell(cell) << " V: " << _verticalScoreOfCell(cell) << ">";
+    }
+    else if (std::is_same<TGapCosts, DynamicGaps>::value)
+    {
+        stream << " <H: " << isGapExtension(cell, DynamicGapExtensionHorizontal{}) <<
+                  " V: " << isGapExtension(cell, DynamicGapExtensionVertical{}) << ">";
+    }
+    return stream;
+}
+
 }  // namespace seqan
 
 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_CELL_H_
diff --git a/include/seqan/align/dp_cell_affine.h b/include/seqan/align/dp_cell_affine.h
index c12990c..88f2af3 100644
--- a/include/seqan/align/dp_cell_affine.h
+++ b/include/seqan/align/dp_cell_affine.h
@@ -62,7 +62,7 @@ public:
     TScoreValue _score              = DPCellDefaultInfinity<DPCell_>::VALUE;
     TScoreValue _horizontalScore    = DPCellDefaultInfinity<DPCell_>::VALUE;
     TScoreValue _verticalScore      = DPCellDefaultInfinity<DPCell_>::VALUE;
-    
+
     DPCell_() = default;
     // Copy c'tor.
     DPCell_(DPCell_<TScoreValue, AffineGaps> const & other) :
@@ -70,7 +70,7 @@ public:
         _horizontalScore(other._horizontalScore),
         _verticalScore(other._verticalScore)
     {}
-    
+
     // Move c-tor
     DPCell_(DPCell_ && other) : DPCell_()
     {
@@ -105,6 +105,19 @@ public:
 // ============================================================================
 
 // ----------------------------------------------------------------------------
+// Function operator<<()
+// ----------------------------------------------------------------------------
+
+// Needed for banded chain alignment for the set.
+template <typename TStream, typename TScore>
+inline TStream& operator<<(TStream & stream,
+                           DPCell_<TScore, AffineGaps> const & dpCell)
+{
+    stream << "<S = " << dpCell._score << " H = " << dpCell._horizontalScore << " V = " << dpCell._verticalScore << ">";
+    return stream;
+}
+
+// ----------------------------------------------------------------------------
 // Function operator<()
 // ----------------------------------------------------------------------------
 
@@ -150,6 +163,13 @@ _setVerticalScoreOfCell(DPCell_<TScoreValue, AffineGaps> & dpCell, TScoreValue c
 
 template <typename TScoreValue>
 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >,void)
+_setVerticalScoreOfCell(DPCell_<TScoreValue, AffineGaps> & dpCell, TScoreValue const & newVerticalScore)
+{
+    dpCell._verticalScore = newVerticalScore;
+}
+
+template <typename TScoreValue>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >,void)
 _setVerticalScoreOfCell(DPCell_<TScoreValue, AffineGaps> & dpCell, TScoreValue const & newVerticalScore, TScoreValue const & mask)
 {
     dpCell._verticalScore = blend(dpCell._verticalScore, newVerticalScore, mask);
@@ -188,14 +208,21 @@ _setHorizontalScoreOfCell(DPCell_<TScoreValue, AffineGaps> & dpCell, TScoreValue
 
 template <typename TScoreValue>
 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >,void)
+_setHorizontalScoreOfCell(DPCell_<TScoreValue, AffineGaps> & dpCell, TScoreValue const & newHorizontalScore)
+{
+    dpCell._horizontalScore = newHorizontalScore;
+}
+
+template <typename TScoreValue>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >,void)
 _setHorizontalScoreOfCell(DPCell_<TScoreValue, AffineGaps> & dpCell, TScoreValue const & newHorizontalScore, TScoreValue const & mask)
 {
     dpCell._horizontalScore = blend(dpCell._horizontalScore, newHorizontalScore, mask);
 }
 
 template <typename TScoreValue>
-inline void 
-swap(DPCell_<TScoreValue, AffineGaps> & lhs, 
+inline void
+swap(DPCell_<TScoreValue, AffineGaps> & lhs,
      DPCell_<TScoreValue, AffineGaps> & rhs)
 {
     std::swap(lhs._score, rhs._score);
diff --git a/include/seqan/align/dp_cell_dynamic.h b/include/seqan/align/dp_cell_dynamic.h
index 567d5f9..90e9e7d 100644
--- a/include/seqan/align/dp_cell_dynamic.h
+++ b/include/seqan/align/dp_cell_dynamic.h
@@ -67,12 +67,6 @@ struct FlagMaskType
 // Tags, Classes, Enums
 // ============================================================================
 
-struct DynamicGapExtensionHorizontal_;
-typedef Tag<DynamicGapExtensionHorizontal_> DynamicGapExtensionHorizontal;
-
-struct DynamicGapExtensionVertical_;
-typedef Tag<DynamicGapExtensionVertical_> DynamicGapExtensionVertical;
-
 enum DynamicGapsMask
 {
     MASK_VERTICAL_GAP = 1,
@@ -168,7 +162,7 @@ inline void _setBit(DPCell_<TScoreValue, DynamicGaps> & cell,
                     TFlag const & /*flag*/,
                     DynamicGapExtensionVertical const & /*tag*/)
 {
-    if (IsSameType<TFlag, True>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TFlag, True>::VALUE)
         cell._flagMask |= MASK_VERTICAL_GAP;
     else
         cell._flagMask &= ~MASK_VERTICAL_GAP;
@@ -179,7 +173,7 @@ inline void _setBit(DPCell_<TScoreValue, DynamicGaps> & cell,
                     TFlag const & /*flag*/,
                     DynamicGapExtensionHorizontal const & /*tag*/)
 {
-    if (IsSameType<TFlag, True>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TFlag, True>::VALUE)
         cell._flagMask |= MASK_HORIZONTAL_GAP;
     else
         cell._flagMask &= ~MASK_HORIZONTAL_GAP;
@@ -190,7 +184,7 @@ inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >,bool)
 isGapExtension(DPCell_<TScoreValue, DynamicGaps> const & cell,
                TSpec const & /*spec*/)
 {
-    if (IsSameType<TSpec, DynamicGapExtensionHorizontal>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TSpec, DynamicGapExtensionHorizontal>::VALUE)
         return cell._flagMask & MASK_HORIZONTAL_GAP;
     else
         return cell._flagMask & MASK_VERTICAL_GAP;
diff --git a/include/seqan/align/dp_context.h b/include/seqan/align/dp_context.h
index 3049369..f3790f7 100644
--- a/include/seqan/align/dp_context.h
+++ b/include/seqan/align/dp_context.h
@@ -57,12 +57,11 @@ struct GetDPTraceMatrix
 // Tags, Classes, Enums
 // ============================================================================
 
-template <typename TScoreValue, typename TGapCosts>
+template <typename TScoreValue, typename TTraceValue,
+          typename TScoreMatrixHost = String<TScoreValue>,
+          typename TTraceMatrixHost = String<TTraceValue> >
 struct DPContext
 {
-    typedef typename GetDPScoreMatrix<DPContext>::Type TScoreMatrixHost;
-    typedef typename GetDPTraceMatrix<DPContext>::Type TTraceMatrixHost;
-
     TScoreMatrixHost _scoreMatrix;
     TTraceMatrixHost _traceMatrix;
 
@@ -74,50 +73,6 @@ struct DPContext
 // Metafunctions
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Metafunction GetDPScoreMatrix
-// ----------------------------------------------------------------------------
-
-template <typename TScoreValue, typename TGapCosts>
-struct GetDPScoreMatrix<DPContext<TScoreValue, TGapCosts> >
-{
-    typedef DPCell_<TScoreValue, TGapCosts> TDPScoreValue_;
-    typedef DPMatrix_<TDPScoreValue_, FullDPMatrix> TDPScoreMatrix_;
-
-    typedef typename Host<TDPScoreMatrix_>::Type Type;
-};
-
-template <typename TScoreValue, typename TGapCosts>
-struct GetDPScoreMatrix<DPContext<TScoreValue, TGapCosts> const >
-{
-    typedef DPCell_<TScoreValue, TGapCosts> TDPScoreValue_;
-    typedef DPMatrix_<TDPScoreValue_, FullDPMatrix> TDPScoreMatrix_;
-
-    typedef typename Host<TDPScoreMatrix_>::Type const Type;
-};
-
-// ----------------------------------------------------------------------------
-// Metafunction GetDPTraceMatrix
-// ----------------------------------------------------------------------------
-
-template <typename TScoreValue, typename TGapCosts>
-struct GetDPTraceMatrix<DPContext<TScoreValue, TGapCosts> >
-{
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue_;
-    typedef DPMatrix_<TTraceValue_, FullDPMatrix> TDPScoreMatrix_;
-
-    typedef typename Host<TDPScoreMatrix_>::Type Type;
-};
-
-template <typename TScoreValue, typename TGapCosts>
-struct GetDPTraceMatrix<DPContext<TScoreValue, TGapCosts> const >
-{
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue_;
-    typedef DPMatrix_<TTraceValue_, FullDPMatrix> TDPScoreMatrix_;
-
-    typedef typename Host<TDPScoreMatrix_>::Type const Type;
-};
-
 // ============================================================================
 // Functions
 // ============================================================================
@@ -126,16 +81,16 @@ struct GetDPTraceMatrix<DPContext<TScoreValue, TGapCosts> const >
 // Function dpScoreMatrix()
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TGapCosts>
-inline typename GetDPScoreMatrix<DPContext<TScoreValue, TGapCosts> >::Type &
-getDpScoreMatrix(DPContext<TScoreValue, TGapCosts> & dpContext)
+template <typename TScoreValue, typename TGapCosts, typename TScoreMatHost, typename TTraceMatHost>
+inline TScoreMatHost &
+getDpScoreMatrix(DPContext<TScoreValue, TGapCosts, TScoreMatHost, TTraceMatHost> & dpContext)
 {
     return dpContext._scoreMatrix;
 }
 
-template <typename TScoreValue, typename TGapCosts>
-inline typename GetDPScoreMatrix<DPContext<TScoreValue, TGapCosts> const >::Type &
-getDpScoreMatrix(DPContext<TScoreValue, TGapCosts> const & dpContext)
+template <typename TScoreValue, typename TGapCosts, typename TScoreMatHost, typename TTraceMatHost>
+inline TScoreMatHost const &
+getDpScoreMatrix(DPContext<TScoreValue, TGapCosts, TScoreMatHost, TTraceMatHost> const & dpContext)
 {
     return dpContext._scoreMatrix;
 }
@@ -144,16 +99,16 @@ getDpScoreMatrix(DPContext<TScoreValue, TGapCosts> const & dpContext)
 // Function dpTraceMatrix()
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TGapCosts>
-inline typename GetDPTraceMatrix<DPContext<TScoreValue, TGapCosts> >::Type &
-getDpTraceMatrix(DPContext<TScoreValue, TGapCosts> & dpContext)
+template <typename TScoreValue, typename TGapCosts, typename TScoreMatHost, typename TTraceMatHost>
+inline TTraceMatHost &
+getDpTraceMatrix(DPContext<TScoreValue, TGapCosts, TScoreMatHost, TTraceMatHost> & dpContext)
 {
     return dpContext._traceMatrix;
 }
 
-template <typename TScoreValue, typename TGapCosts>
-inline typename GetDPTraceMatrix<DPContext<TScoreValue, TGapCosts> const >::Type &
-getDpTraceMatrix(DPContext<TScoreValue, TGapCosts> const & dpContext)
+template <typename TScoreValue, typename TGapCosts, typename TScoreMatHost, typename TTraceMatHost>
+inline TTraceMatHost const &
+getDpTraceMatrix(DPContext<TScoreValue, TGapCosts, TScoreMatHost, TTraceMatHost> const & dpContext)
 {
     return dpContext._traceMatrix;
 }
@@ -162,10 +117,10 @@ getDpTraceMatrix(DPContext<TScoreValue, TGapCosts> const & dpContext)
 // Function setDpScoreMatrix()
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TGapCosts>
+template <typename TScoreValue, typename TGapCosts, typename TScoreMatHost, typename TTraceMatHost>
 inline void
-setDpTraceMatrix(DPContext<TScoreValue, TGapCosts> & dpContext,
-                typename GetDPScoreMatrix<DPContext<TScoreValue, TGapCosts> >::Type const & scoreMatrix)
+setDpTraceMatrix(DPContext<TScoreValue, TGapCosts, TScoreMatHost, TTraceMatHost> & dpContext,
+                 TScoreMatHost const & scoreMatrix)
 {
     dpContext._scoreMatrix = scoreMatrix;
 }
@@ -174,10 +129,10 @@ setDpTraceMatrix(DPContext<TScoreValue, TGapCosts> & dpContext,
 // Function setDpTraceMatrix()
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TGapCosts>
+template <typename TScoreValue, typename TGapCosts, typename TScoreMatHost, typename TTraceMatHost>
 inline void
-setDpTraceMatrix(DPContext<TScoreValue, TGapCosts> & dpContext,
-                typename GetDPTraceMatrix<DPContext<TScoreValue, TGapCosts> >::Type const & traceMatrix)
+setDpTraceMatrix(DPContext<TScoreValue, TGapCosts, TScoreMatHost, TTraceMatHost> & dpContext,
+                 TTraceMatHost const & traceMatrix)
 {
     dpContext._tarceMatrix = traceMatrix;
 }
diff --git a/include/seqan/align/dp_formula.h b/include/seqan/align/dp_formula.h
index 9ecd0ab..9bb120f 100644
--- a/include/seqan/align/dp_formula.h
+++ b/include/seqan/align/dp_formula.h
@@ -34,8 +34,6 @@
 // Defines the recursion formula for the dp-alignment algorithms.
 // ==========================================================================
 
-// TODO(holtgrew): Documentation in this header necessary or internal only?
-
 #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_FORMULA_H_
 #define SEQAN_INCLUDE_SEQAN_ALIGN_DP_FORMULA_H_
 
@@ -102,116 +100,191 @@ typedef Tag<RecursionDirectionZero_> RecursionDirectionZero;
 // Metafunctions
 // ============================================================================
 
+// Helper typedef to get the correct score value type from the score-matrix navigator.
+template <typename TCellTuple>
+using ExtractedScoreValueType_ = std::decay_t<decltype(_scoreOfCell(std::get<0>(std::declval<TCellTuple>())))>;
+
 // ============================================================================
 // Functions
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Function _computeScore
-// ----------------------------------------------------------------------------
+template <typename TTarget,
+          typename TSourceLeft,
+          typename TSourceRight,
+          typename TTraceLeft,
+          typename TTraceRight>
+inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TTarget>>>, typename TraceBitMap_<TTarget>::Type)
+_maxScore(TTarget & target,
+          TSourceLeft const & srcLeft,
+          TSourceRight const & srcRight,
+          TTraceRight const /**/,
+          TTraceLeft const  /**/,
+          TracebackOff const & /*tag*/)
+{
+    using std::max;
+    target = max(static_cast<TTarget>(srcLeft), static_cast<TTarget>(srcRight));
+    return TraceBitMap_<TTarget>::NONE;
+}
 
-template <typename TScoreValue, typename TGapCosts, typename TSequenceHValue, typename TSequenceVValue,
-          typename TScoringScheme, typename TRecursionDirection, typename TDPProfile>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_computeScore(DPCell_<TScoreValue, TGapCosts> & activeCell,
-              DPCell_<TScoreValue, TGapCosts> const & previousDiagonal,
-              DPCell_<TScoreValue, TGapCosts> const & previousHorizontal,
-              DPCell_<TScoreValue, TGapCosts> const & previousVertical,
-              TSequenceHValue const & seqHVal,
-              TSequenceVValue const & seqVVal,
-              TScoringScheme const & scoringScheme,
-              TRecursionDirection const & recDir,
-              TDPProfile const & dpProfile)
+template <typename TTarget,
+          typename TSourceLeft,
+          typename TSourceRight,
+          typename TTraceLeft,
+          typename TTraceRight>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TTarget>>, typename TraceBitMap_<TTarget>::Type)
+_maxScore(TTarget & target,
+          TSourceLeft const & srcLeft,
+          TSourceRight const & srcRight,
+          TTraceRight const /**/,
+          TTraceLeft const  /**/,
+          TracebackOff const & /*tag*/)
 {
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-
-    TTraceValue traceDir = _doComputeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal,
-                                           seqVVal, scoringScheme, recDir, dpProfile);
-    if (IsLocalAlignment_<TDPProfile>::VALUE)
-        if (activeCell._score <= 0)
-        {
-            _setScoreOfCell(activeCell, static_cast<TScoreValue>(0));
-            _setHorizontalScoreOfCell(activeCell, static_cast<TScoreValue>(0));
-            _setVerticalScoreOfCell(activeCell, static_cast<TScoreValue>(0));
-            return TraceBitMap_<TScoreValue>::NONE;
-        }
-
-    return traceDir;
+    target = max(srcLeft, srcRight);
+    return TraceBitMap_<TTarget>::NONE;
 }
 
-template <typename TScoreValue, typename TGapCosts, typename TSequenceHValue, typename TSequenceVValue,
-          typename TScoringScheme, typename TRecursionDirection, typename TDPProfile>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_computeScore(DPCell_<TScoreValue, TGapCosts> & activeCell,
-              DPCell_<TScoreValue, TGapCosts> const & previousDiagonal,
-              DPCell_<TScoreValue, TGapCosts> const & previousHorizontal,
-              DPCell_<TScoreValue, TGapCosts> const & previousVertical,
-              TSequenceHValue const & seqHVal,
-              TSequenceVValue const & seqVVal,
-              TScoringScheme const & scoringScheme,
-              TRecursionDirection const & recDir,
-              TDPProfile const & dpProfile)
+template <typename TTarget,
+          typename TSourceLeft,
+          typename TSourceRight,
+          typename TTraceLeft,
+          typename TTraceRight,
+          typename TGapsPlacement>
+inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TTarget>>>, typename TraceBitMap_<TTarget>::Type)
+_maxScore(TTarget & target,
+          TSourceLeft const & srcLeft,
+          TSourceRight const & srcRight,
+          TTraceLeft const  traceLeft,
+          TTraceRight const traceRight,
+          TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > const & /*tag*/)
 {
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
+    return (srcLeft < srcRight)
+        ? (target = srcRight, traceRight)
+        : (target = srcLeft, traceLeft);
+}
 
-    TTraceValue traceDir = _doComputeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal,
-                                           seqVVal, scoringScheme, recDir, dpProfile);
-    if (IsLocalAlignment_<TDPProfile>::VALUE)
-    {
-        TScoreValue cmp = cmpGt(createVector<TScoreValue>(1), activeCell._score);
-        _setScoreOfCell(activeCell, TraceBitMap_<TScoreValue>::NONE, cmp);
-        _setHorizontalScoreOfCell(activeCell, TraceBitMap_<TScoreValue>::NONE, cmp);
-        _setVerticalScoreOfCell(activeCell, TraceBitMap_<TScoreValue>::NONE, cmp);
-        return blend(traceDir, TraceBitMap_<TScoreValue>::NONE, cmp);
-    }
+template <typename TTarget,
+          typename TSourceLeft,
+          typename TSourceRight,
+          typename TTraceLeft,
+          typename TTraceRight,
+          typename TGapsPlacement>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TTarget>>, typename TraceBitMap_<TTarget>::Type)
+_maxScore(TTarget & target,
+          TSourceLeft const & srcLeft,
+          TSourceRight const & srcRight,
+          TTraceLeft const  traceLeft,
+          TTraceRight const traceRight,
+          TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > const & /*tag*/)
+{
+    auto cmp = cmpGt(srcRight, srcLeft);
+    target = blend(srcLeft, srcRight, cmp);
+    return blend(traceLeft, traceRight, cmp);
+}
+
+template <typename TTarget,
+          typename TSourceLeft,
+          typename TSourceRight,
+          typename TTraceLeft,
+          typename TTraceRight,
+          typename TGapsPlacement>
+inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TTarget>>>, typename TraceBitMap_<TTarget>::Type)
+_maxScore(TTarget & target,
+          TSourceLeft const & srcLeft,
+          TSourceRight const & srcRight,
+          TTraceLeft const  traceLeft,
+          TTraceRight const traceRight,
+          TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> > const & /*tag*/)
+{
+    return (srcLeft == srcRight)
+        ? (target = srcLeft, traceLeft | traceRight)
+        : (srcLeft < srcRight)
+            ? (target = srcRight, traceRight)
+            : (target = srcLeft, traceLeft);
+}
 
-    return traceDir;
+template <typename TTarget,
+          typename TSourceLeft,
+          typename TSourceRight,
+          typename TTraceLeft,
+          typename TTraceRight,
+          typename TGapsPlacement>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TTarget>>, typename TraceBitMap_<TTarget>::Type)
+_maxScore(TTarget & target,
+          TSourceLeft const & srcLeft,
+          TSourceRight const & srcRight,
+          TTraceLeft const  traceLeft,
+          TTraceRight const traceRight,
+          TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> > const & /*tag*/)
+{
+    auto cmpG = cmpGt(srcRight, srcLeft);
+    auto cmpE = cmpEq(srcRight, srcLeft);
+    target = blend(srcLeft, srcRight, cmpG);
+    auto result = blend(traceLeft, traceRight, cmpG);
+    return blend(result, traceLeft | traceRight, cmpE);
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore                        [RecursionDirectionDiagonal]
+// Function _computeScore                          [RecursionDirectionDiagonal]
 // ----------------------------------------------------------------------------
-
-template <typename TScoreValue, typename TGapCosts, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TDPProfile>
-inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, TGapCosts> & activeCell,
-                DPCell_<TScoreValue, TGapCosts> const & previousDiagonal,
-                DPCell_<TScoreValue, TGapCosts> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, TGapCosts> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionDiagonal const &,
-                TDPProfile const &)
+// Independent of gap cost model.
+template <typename TScoreValue, typename TGapCosts,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline auto
+_computeScore(DPCell_<TScoreValue, TGapCosts> & current,
+              DPCell_<TScoreValue, TGapCosts> & diagonal,
+              DPCell_<TScoreValue, TGapCosts> const & /*horizontal*/,
+              DPCell_<TScoreValue, TGapCosts> const & /*vertical*/,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionDiagonal const &,
+              DPProfile_<TAlgorithm, TGapCosts, TTracebackConfig, TExecPolicy> const &)
 {
-    activeCell._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    setGapExtension(activeCell, False(), False(), createVector<TScoreValue>(-1));
+    _scoreOfCell(current) = _scoreOfCell(diagonal) + score(scoringScheme, seqHVal, seqVVal);
+    setGapExtension(current, False(), False(), createVector<TScoreValue>(-1));
 
-    if (!IsTracebackEnabled_<TDPProfile>::VALUE)
-        return TraceBitMap_<TScoreValue>::NONE;
-
-    return TraceBitMap_<TScoreValue>::DIAGONAL;
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        return _maxScore(_scoreOfCell(current),
+                         TraceBitMap_<TScoreValue>::NONE,
+                         _scoreOfCell(current),
+                         TraceBitMap_<TScoreValue>::NONE,
+                         TraceBitMap_<TScoreValue>::DIAGONAL,
+                         TTracebackConfig{});
+    }
+    else
+    {
+        return TraceBitMap_<TScoreValue>::DIAGONAL;
+    }
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore                            [RecursionDirectionZero]
+// Function _computeScore                              [RecursionDirectionZero]
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TGapCosts, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgoTag, typename TTraceFlag>
-inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, TGapCosts> & activeCell,
-                DPCell_<TScoreValue, TGapCosts> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, TGapCosts> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, TGapCosts> const & /*previousVertical*/,
-                TSequenceHValue const & /*seqHVal*/,
-                TSequenceVValue const & /*seqVVal*/,
-                TScoringScheme const & /*scoringScheme*/,
-                RecursionDirectionZero const &,
-                DPProfile_<TAlgoTag, TGapCosts, TTraceFlag> const &)
+// Independent of gap cost model.
+template <typename TScoreValue, typename TGapCosts,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TAlgoTag, typename TTraceFlag, typename TExecPolicy>
+inline auto
+_computeScore(DPCell_<TScoreValue, TGapCosts> & current,
+              DPCell_<TScoreValue, TGapCosts> & diagonal,
+              DPCell_<TScoreValue, TGapCosts> const & /*horizontal*/,
+              DPCell_<TScoreValue, TGapCosts> & vertical,
+              TSequenceHValue const & /*seqHVal*/,
+              TSequenceVValue const & /*seqVVal*/,
+              TScoringScheme const & /*scoringScheme*/,
+              RecursionDirectionZero const &,
+              DPProfile_<TAlgoTag, TGapCosts, TTraceFlag, TExecPolicy> const &)
 {
-    _scoreOfCell(activeCell) = createVector<TScoreValue>(0);
+    _scoreOfCell(current) = TraceBitMap_<TScoreValue>::NONE;
+    _scoreOfCell(diagonal) = _scoreOfCell(current);
+    _scoreOfCell(vertical) = _scoreOfCell(current);
     return TraceBitMap_<TScoreValue>::NONE;
 }
 
diff --git a/include/seqan/align/dp_formula_affine.h b/include/seqan/align/dp_formula_affine.h
index 2e22c0c..ea5b975 100644
--- a/include/seqan/align/dp_formula_affine.h
+++ b/include/seqan/align/dp_formula_affine.h
@@ -56,579 +56,272 @@ namespace seqan {
 // ============================================================================
 
 // ----------------------------------------------------------------------------
-// Function _internalComputeScore      [RecursionDirectionDiagonal, AffineGaps]
+// Function _computeScore                 [RecursionAllDirection, AffineGaps]
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TAffineGaps, typename TTraceValueL, typename TTraceValueGap>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, TAffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL,
-                      TTraceValueGap,
-                      TracebackOff const &,
-                      RecursionDirectionDiagonal const &)
-{
-    if(activeCell._score < rightCompare)
-        activeCell._score = rightCompare;
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TAffineGaps, typename TTraceValueL, typename TTraceValueGap>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, TAffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL,
-                      TTraceValueGap,
-                      TracebackOff const &,
-                      RecursionDirectionDiagonal const &)
-{
-    activeCell._score = blend(activeCell._score, rightCompare, cmpGt(rightCompare, activeCell._score));
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TAffineGaps, typename TTraceValueL, typename TTraceValueGap, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, TAffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueGap gapTrace,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > const &,
-                      RecursionDirectionDiagonal const &)
-{
-    if(activeCell._score <= rightCompare)
-    {
-        activeCell._score = rightCompare;
-        return TraceBitMap_<TScoreValue>::DIAGONAL | leftTrace;
-    }
-    return leftTrace | gapTrace;
-}
-
-template <typename TScoreValue, typename TAffineGaps, typename TTraceValueL, typename TTraceValueGap, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, TAffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL const & leftTrace,
-                      TTraceValueGap const & gapTrace,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > const &,
-                      RecursionDirectionDiagonal const &)
-{
-    TScoreValue cmp = cmpGt(activeCell._score, rightCompare);
-    activeCell._score = blend(rightCompare, activeCell._score, cmp);
-    return blend(TraceBitMap_<TScoreValue>::DIAGONAL | leftTrace,
-                 leftTrace | gapTrace,
-                 cmp);
-}
-
-template <typename TScoreValue, typename TAffineGaps, typename TTraceValueL, typename TTraceValueGap, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, TAffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueGap gapTrace,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionDiagonal const &)
+template <typename TScoreValue,
+          typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, AffineGaps> & current,
+              DPCell_<TScoreValue, AffineGaps> & previousDiagonal,
+              DPCell_<TScoreValue, AffineGaps> const & previousHorizontal,
+              DPCell_<TScoreValue, AffineGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionAll const &,
+              DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    if(activeCell._score < rightCompare)
+    // Compute intermediate diagonal result.
+    TScoreValue intermediate = static_cast<TScoreValue>(_scoreOfCell(previousDiagonal) +
+                                                        score(scoringScheme, seqHVal, seqVVal));
+    // Cache previous Diagonal
+    _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal);
+    // Compute horizontal direction.
+    auto tmp  = _maxScore(_horizontalScoreOfCell(current),
+                          _horizontalScoreOfCell(previousHorizontal) +
+                              scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal),
+                          _scoreOfCell(previousHorizontal) +
+                              scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal),
+                          TraceBitMap_<TScoreValue>::HORIZONTAL,
+                          TraceBitMap_<TScoreValue>::HORIZONTAL_OPEN,
+                          TTracebackConfig{});
+
+    // Compute vertical direction.
+    tmp |= _maxScore(_verticalScoreOfCell(previousVertical),
+                     _verticalScoreOfCell(previousVertical) +
+                         scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal),
+                     _scoreOfCell(previousVertical) +
+                         scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal),
+                     TraceBitMap_<TScoreValue>::VERTICAL,
+                     TraceBitMap_<TScoreValue>::VERTICAL_OPEN,
+                     TTracebackConfig{});
+
+    auto tmp2 = _maxScore(_scoreOfCell(current),
+                    _verticalScoreOfCell(previousVertical),
+                    _horizontalScoreOfCell(current),
+                    TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
+                    TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
+                    TTracebackConfig{});
+    tmp = _maxScore(_scoreOfCell(current),
+                    intermediate,
+                    _scoreOfCell(current),
+                    TraceBitMap_<TScoreValue>::DIAGONAL | tmp,
+                    tmp2 | tmp,
+                    TTracebackConfig{});
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
     {
-        activeCell._score = rightCompare;  // Maximal score comes from diagonal.
-        return TraceBitMap_<TScoreValue>::DIAGONAL | leftTrace;  // Return trace for Diagonal.
+        tmp = _maxScore(_scoreOfCell(current),
+                        TraceBitMap_<TScoreValue>::NONE,
+                        _scoreOfCell(current),
+                        TraceBitMap_<TScoreValue>::NONE,
+                        tmp,
+                        TTracebackConfig{});
     }
-    if (activeCell._score == rightCompare)      // Maximal score comes from previous computed directions and diagonal.
-        return leftTrace | TraceBitMap_<TScoreValue>::DIAGONAL | gapTrace;   // Return all directions inclusively the flag indicating max from gap.
-    return leftTrace | gapTrace; // Maximum comes from gap. Return gap value inclusively the flag indicating max from gap.
-}
-
-template <typename TScoreValue, typename TAffineGaps, typename TTraceValueL, typename TTraceValueGap, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, TAffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL const & leftTrace,
-                      TTraceValueGap const & gapTrace,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionDiagonal const &)
-{
-    TScoreValue cmpG = cmpGt(rightCompare, activeCell._score);
-    TScoreValue cmpE = cmpEq(rightCompare, activeCell._score);
-    TScoreValue result = leftTrace | gapTrace;
-    activeCell._score = blend(activeCell._score, rightCompare, cmpG);
-    result = blend(result, TraceBitMap_<TScoreValue>::DIAGONAL | leftTrace, cmpG);
-    return blend(result, leftTrace | TraceBitMap_<TScoreValue>::DIAGONAL | gapTrace, cmpE);
+    // Cache score for previous vertical.
+    _scoreOfCell(previousVertical) = _scoreOfCell(current);
+    return tmp;
 }
 
 // ----------------------------------------------------------------------------
-// Function _internalComputeScore    [RecursionDirectionHorizontal, AffineGaps]
+// Function _computeScore       [RecursionUpperDiagonalDirection, AffineGaps]
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL,
-                      TTraceValueR,
-                      TracebackOff const &,
-                      RecursionDirectionHorizontal const &)
-{
-    if(activeCell._horizontalScore < rightCompare)
-        activeCell._score = activeCell._horizontalScore = rightCompare;
-    else
-        activeCell._score = activeCell._horizontalScore;
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL,
-                      TTraceValueR,
-                      TracebackOff const &,
-                      RecursionDirectionHorizontal const &)
-{
-    TScoreValue cmp = cmpGt(rightCompare, activeCell._horizontalScore);
-    activeCell._horizontalScore = blend(activeCell._horizontalScore, rightCompare, cmp);
-    activeCell._score = activeCell._horizontalScore;
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueR  rightTrace,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionHorizontal const &)
-{
-    if(activeCell._horizontalScore < rightCompare)
-    {
-        activeCell._score = activeCell._horizontalScore = rightCompare;
-        return rightTrace;
-    }
-    activeCell._score = activeCell._horizontalScore;
-    return leftTrace;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueR  rightTrace,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionHorizontal const &)
+template <typename TScoreValue,
+          typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, AffineGaps> & current,
+              DPCell_<TScoreValue, AffineGaps> & previousDiagonal,
+              DPCell_<TScoreValue, AffineGaps> const & previousHorizontal,
+              DPCell_<TScoreValue, AffineGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionUpperDiagonal const &,
+              DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    TScoreValue cmp = cmpGt(rightCompare, activeCell._horizontalScore);
-    activeCell._horizontalScore = blend(activeCell._horizontalScore, rightCompare, cmp);
-    activeCell._score = activeCell._horizontalScore;
-    return blend(leftTrace, rightTrace, cmp);
-}
+    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
 
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueR rightTrace,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionHorizontal const &)
-{
-    if(activeCell._horizontalScore < rightCompare)
+    // Compute intermediate diagonal result.
+    TScoreValue intermediate = static_cast<TScoreValue>(_scoreOfCell(previousDiagonal) +
+                                                        score(scoringScheme, seqHVal, seqVVal));
+    // Cache previous Diagonal
+    _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal);
+    // Compute horiztonal direction.
+    // _horizontalScoreOfCell(current) = _horizontalScoreOfCell(previousHorizontal) +
+    //                                      scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
+    TTraceValue tv = _maxScore(_horizontalScoreOfCell(current),
+                               _horizontalScoreOfCell(previousHorizontal) +
+                                    scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal),
+                               _scoreOfCell(previousHorizontal) +
+                                    scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal),
+                               TraceBitMap_<TScoreValue>::HORIZONTAL,
+                               TraceBitMap_<TScoreValue>::HORIZONTAL_OPEN,
+                               TTracebackConfig());
+    // Ignore vertical direction in upper diagonal.
+    _verticalScoreOfCell(previousVertical) = DPCellDefaultInfinity<DPCell_<TScoreValue, AffineGaps> >::VALUE;
+    // Compute diagonal direction and compare with horizontal.
+    // _scoreOfCell(current) = _horizontalScoreOfCell(current);
+    tv = _maxScore(_scoreOfCell(current),
+                   intermediate,
+                   _horizontalScoreOfCell(current),
+                   tv | TraceBitMap_<TScoreValue>::DIAGONAL,
+                   tv | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
+                   TTracebackConfig());
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
     {
-        activeCell._score = activeCell._horizontalScore = rightCompare;
-        return rightTrace;
+        tv = _maxScore(_scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
     }
-    activeCell._score = activeCell._horizontalScore;
-    if (activeCell._horizontalScore == rightCompare)
-        return leftTrace | rightTrace;
-    return leftTrace;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL const & leftTrace,
-                      TTraceValueR const & rightTrace,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionHorizontal const &)
-{
-    TScoreValue cmpG = cmpGt(rightCompare, activeCell._horizontalScore);
-    TScoreValue cmpE = cmpEq(rightCompare, activeCell._horizontalScore);
-    activeCell._horizontalScore = blend(activeCell._horizontalScore, rightCompare, cmpG);
-    activeCell._score = activeCell._horizontalScore;
-
-    TScoreValue result = leftTrace;
-    result = blend(result, rightTrace, cmpG);
-    return blend(result, leftTrace | rightTrace, cmpE);
+    _scoreOfCell(previousVertical) = _scoreOfCell(current);
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _internalComputeScore      [RecursionDirectionVertical, AffineGaps]
+// Function _computeScore       [RecursionDirectionLowerDiagonal, AffineGaps]
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL,
-                      TTraceValueR,
-                      TracebackOff const &,
-                      RecursionDirectionVertical const &)
-{
-    if(activeCell._verticalScore < rightCompare)
-        activeCell._score = activeCell._verticalScore = rightCompare;
-    else
-        activeCell._score = activeCell._verticalScore;
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL,
-                      TTraceValueR,
-                      TracebackOff const &,
-                      RecursionDirectionVertical const &)
-{
-    TScoreValue cmp = cmpGt(rightCompare, activeCell._verticalScore);
-    activeCell._verticalScore = blend(activeCell._verticalScore, rightCompare, cmp);
-    activeCell._score = activeCell._verticalScore;
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueR rightTrace,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionVertical const &)
-{
-    if(activeCell._verticalScore < rightCompare)
-    {
-        activeCell._score = activeCell._verticalScore = rightCompare;
-        return rightTrace;
-    }
-    activeCell._score = activeCell._verticalScore;
-    return leftTrace;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL const & leftTrace,
-                      TTraceValueR const & rightTrace,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionVertical const &)
+template <typename TScoreValue,
+          typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, AffineGaps> & current,
+              DPCell_<TScoreValue, AffineGaps> const & previousDiagonal,
+              DPCell_<TScoreValue, AffineGaps> const & /*previousHorizontal*/,
+              DPCell_<TScoreValue, AffineGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionLowerDiagonal const &,
+              DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    TScoreValue cmp = cmpGt(rightCompare, activeCell._verticalScore);
-    activeCell._verticalScore = blend(activeCell._verticalScore, rightCompare, cmp);
-    activeCell._score = activeCell._verticalScore;
-    return blend(leftTrace, rightTrace, cmp);
-}
+    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
 
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueR rightTrace,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionVertical const &)
-{
-    if(activeCell._verticalScore < rightCompare)
+    // Compute vertical direction.
+    TTraceValue tv = _maxScore(_verticalScoreOfCell(previousVertical),
+                               _verticalScoreOfCell(previousVertical) +
+                                    scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal),
+                               _scoreOfCell(previousVertical) +
+                                    scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal),
+                              TraceBitMap_<TScoreValue>::VERTICAL,
+                              TraceBitMap_<TScoreValue>::VERTICAL_OPEN,
+                              TTracebackConfig());
+    // Ignore horizontal direction in lower diagonal.
+    _horizontalScoreOfCell(current) = DPCellDefaultInfinity<DPCell_<TScoreValue, AffineGaps> >::VALUE;
+
+    // Compute diagonal direction and compare with vertical.
+    tv = _maxScore(_scoreOfCell(current),
+                   _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal),
+                   _verticalScoreOfCell(previousVertical),
+                   tv | TraceBitMap_<TScoreValue>::DIAGONAL,
+                   tv | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
+                   TTracebackConfig());
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
     {
-        activeCell._score = activeCell._verticalScore = rightCompare;
-        return rightTrace;
+        tv = _maxScore(_scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
     }
-    activeCell._score = activeCell._verticalScore;
-    if (activeCell._verticalScore == rightCompare)
-        return leftTrace | rightTrace;
-    return leftTrace;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueR rightTrace,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &,
-                      RecursionDirectionVertical const &)
-{
-    TScoreValue cmpG = cmpGt(rightCompare, activeCell._verticalScore);
-    TScoreValue cmpE = cmpEq(rightCompare, activeCell._verticalScore);
-    activeCell._verticalScore = blend(activeCell._verticalScore, rightCompare, cmpG);
-    activeCell._score = activeCell._verticalScore;
-
-    TScoreValue result = leftTrace;
-    result = blend(result, rightTrace, cmpG);
-    return blend(result, leftTrace | rightTrace, cmpE);
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _internalComputeScore          [Vertical vs Horizontal, AffineGaps]
+// Function _computeScore                      [RecursionHorizontalDirection]
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TracebackOff const &)
-{
-    if(activeCell._score < activeCell._horizontalScore)
-        activeCell._score = activeCell._horizontalScore;
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TracebackOff const &)
-{
-    activeCell._score = blend(activeCell._score, activeCell._horizontalScore,
-                              cmpGt(activeCell._horizontalScore, activeCell._score));
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> >  const &)
-{
-    if(activeCell._score < activeCell._horizontalScore)
-    {
-        activeCell._score = activeCell._horizontalScore;
-        return TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
-    }
-    return TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
-}
-
-template <typename TScoreValue, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> >  const &)
-{
-    TScoreValue cmp = cmpGt(activeCell._horizontalScore, activeCell._score);
-    activeCell._score = blend(activeCell._score, activeCell._horizontalScore, cmp);
-    return blend(TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
-                 TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
-                 cmp);
-}
-
-template <typename TScoreValue, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &)
+template <typename TScoreValue,
+          typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, AffineGaps> & current,
+              DPCell_<TScoreValue, AffineGaps> & previousDiagonal,
+              DPCell_<TScoreValue, AffineGaps> const & previousHorizontal,
+              DPCell_<TScoreValue, AffineGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionHorizontal const &,
+              DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    if(activeCell._score < activeCell._horizontalScore)
+    // Cache previous diagonal value.
+    _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal);
+    // Compute horizontal direction.
+    auto traceDir = _maxScore(_horizontalScoreOfCell(current),
+                              _horizontalScoreOfCell(previousHorizontal) +
+                                scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal),
+                              _scoreOfCell(previousHorizontal) +
+                                scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal),
+                              TraceBitMap_<TScoreValue>::HORIZONTAL,
+                              TraceBitMap_<TScoreValue>::HORIZONTAL_OPEN,
+                              TTracebackConfig()) | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
+    // Ignore vertical direction.
+    _verticalScoreOfCell(previousVertical) = DPCellDefaultInfinity<DPCell_<TScoreValue, AffineGaps> >::VALUE;
+    _scoreOfCell(current) = _horizontalScoreOfCell(current);
+
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
     {
-        activeCell._score = activeCell._horizontalScore;
-        return TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
+        traceDir = _maxScore(_scoreOfCell(current),
+                             TraceBitMap_<TScoreValue>::NONE,
+                             _scoreOfCell(current),
+                             TraceBitMap_<TScoreValue>::NONE,
+                             traceDir,
+                             TTracebackConfig{});
     }
-    if (activeCell._score == activeCell._horizontalScore)
-        return TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
-    return TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
-}
-
-template <typename TScoreValue, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &)
-{
-    TScoreValue cmpG = cmpGt(activeCell._horizontalScore, activeCell._score);
-    TScoreValue cmpE = cmpEq(activeCell._horizontalScore, activeCell._score);
-    activeCell._score = blend(activeCell._score, activeCell._horizontalScore, cmpG);
-
-    return blend(blend(TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
-                       TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
-                       cmpG),
-                 TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
-                 cmpE);
-}
-
-// ----------------------------------------------------------------------------
-// Function _doComputeScore                 [RecursionAllDirection, AffineGaps]
-// ----------------------------------------------------------------------------
-
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                DPCell_<TScoreValue, AffineGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, AffineGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, AffineGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionAll const &,
-                DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig> const &)
-{
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-
-    // Now we have to find a smart version to solve this problem. Which is not as easy I would think.
-    activeCell._horizontalScore = _horizontalScoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
-    TScoreValue tmpScore = _scoreOfCell(previousHorizontal) + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal);
-    TTraceValue tvGap = _internalComputeScore(activeCell,
-                                              tmpScore,
-                                              TraceBitMap_<TScoreValue>::HORIZONTAL,
-                                              TraceBitMap_<TScoreValue>::HORIZONTAL_OPEN,
-                                              TTracebackConfig(),
-                                              RecursionDirectionHorizontal());
-
-    // Now we can decide for the optimal score in horizontal score or not?
-    activeCell._verticalScore = _verticalScoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-    tmpScore = _scoreOfCell(previousVertical) + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal);
-    tvGap |= _internalComputeScore(activeCell,
-                                   tmpScore,
-                                   TraceBitMap_<TScoreValue>::VERTICAL,
-                                   TraceBitMap_<TScoreValue>::VERTICAL_OPEN,
-                                   TTracebackConfig(),
-                                   RecursionDirectionVertical());
-
-    // Finds the maximum between the vertical and the horizontal matrix. Stores the flag for coming from a potential direction.
-    TTraceValue tvMax = _internalComputeScore(activeCell, TTracebackConfig());  // Stores from where the maximal score comes.
-    tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell, tmpScore, tvGap, tvMax, TTracebackConfig(), RecursionDirectionDiagonal());
-}
-
-// ----------------------------------------------------------------------------
-// Function _doComputeScore       [RecursionUpperDiagonalDirection, AffineGaps]
-// ----------------------------------------------------------------------------
-
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                DPCell_<TScoreValue, AffineGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, AffineGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, AffineGaps> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionUpperDiagonal const &,
-                DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig> const &)
-{
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-
-    activeCell._horizontalScore = _horizontalScoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
-    activeCell._verticalScore = DPCellDefaultInfinity<DPCell_<TScoreValue, AffineGaps> >::VALUE;
-    TScoreValue tmpScore = _scoreOfCell(previousHorizontal) + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal);
-    TTraceValue tv = _internalComputeScore(activeCell,
-                                           tmpScore,
-                                           TraceBitMap_<TScoreValue>::HORIZONTAL,
-                                           TraceBitMap_<TScoreValue>::HORIZONTAL_OPEN,
-                                           TTracebackConfig(),
-                                           RecursionDirectionHorizontal());
-    tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell,
-                                 tmpScore,
-                                 tv,
-                                 TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
-                                 TTracebackConfig(),
-                                 RecursionDirectionDiagonal());
+    _scoreOfCell(previousVertical) = _scoreOfCell(current);
+    return traceDir;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore       [RecursionDirectionLowerDiagonal, AffineGaps]
+// Function _computeScore                        [RecursionVerticalDirection]
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
+template <typename TScoreValue,
+          typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
 inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                DPCell_<TScoreValue, AffineGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, AffineGaps> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, AffineGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionLowerDiagonal const &,
-                DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig> const &)
+_computeScore(DPCell_<TScoreValue, AffineGaps> & current,
+              DPCell_<TScoreValue, AffineGaps> const & /*previousDiagonal*/,
+              DPCell_<TScoreValue, AffineGaps> const & /*previousHorizontal*/,
+              DPCell_<TScoreValue, AffineGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionVertical const &,
+              DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-
-    activeCell._verticalScore = _verticalScoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-    TScoreValue tmpScore = _scoreOfCell(previousVertical) + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal);
-
-    activeCell._horizontalScore = DPCellDefaultInfinity<DPCell_<TScoreValue, AffineGaps> >::VALUE;
-    // This computes the difference between the vertical extend and vertical open.
-    TTraceValue tv = _internalComputeScore(activeCell,
-                                           tmpScore,
-                                           TraceBitMap_<TScoreValue>::VERTICAL,
-                                           TraceBitMap_<TScoreValue>::VERTICAL_OPEN,
-                                           TTracebackConfig(),
-                                           RecursionDirectionVertical());
-
-    // Up to here, activeCell stores the highest value of vertical or vertical open.
-    tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell,
-                                 tmpScore,
-                                 tv,
-                                 TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
-                                 TTracebackConfig(),
-                                 RecursionDirectionDiagonal());  // Now we have this problem. How do we determine if the max comes from the vertical distance.
-}
-
-// ----------------------------------------------------------------------------
-// Function _doComputeScore                      [RecursionHorizontalDirection]
-// ----------------------------------------------------------------------------
-
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                DPCell_<TScoreValue, AffineGaps> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, AffineGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, AffineGaps> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionHorizontal const &,
-                DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig> const &)
-{
-    TScoreValue tmpGapOpenHorizontal = _scoreOfCell(previousHorizontal) + scoreGapOpenHorizontal(scoringScheme, seqHVal, seqVVal);
-    activeCell._horizontalScore = _horizontalScoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
-
-    activeCell._verticalScore = DPCellDefaultInfinity<DPCell_<TScoreValue, AffineGaps> >::VALUE;
-    return _internalComputeScore(activeCell,
-                                tmpGapOpenHorizontal,
-                                TraceBitMap_<TScoreValue>::HORIZONTAL,
-                                TraceBitMap_<TScoreValue>::HORIZONTAL_OPEN,
-                                TTracebackConfig(),
-                                RecursionDirectionHorizontal()) | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
-}
-
-// ----------------------------------------------------------------------------
-// Function _doComputeScore                        [RecursionVerticalDirection]
-// ----------------------------------------------------------------------------
-
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, AffineGaps> & activeCell,
-                DPCell_<TScoreValue, AffineGaps> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, AffineGaps> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, AffineGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionVertical const &,
-                DPProfile_<TAlgorithm, AffineGaps, TTracebackConfig> const &)
-{
-    TScoreValue tmpGapOpenVertical = _scoreOfCell(previousVertical) + scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal);
-    activeCell._verticalScore = _verticalScoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-
-    // Here we distinguish between vertical and vertical open.
-    activeCell._horizontalScore = DPCellDefaultInfinity<DPCell_<TScoreValue, AffineGaps> >::VALUE;
-    return _internalComputeScore(activeCell,
-                                 tmpGapOpenVertical,
-                                 TraceBitMap_<TScoreValue>::VERTICAL,
-                                 TraceBitMap_<TScoreValue>::VERTICAL_OPEN,
-                                 TTracebackConfig(),
-                                 RecursionDirectionVertical()) | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
+    // Compute vertical direction.
+    auto traceDir = _maxScore(_verticalScoreOfCell(previousVertical),
+                              _verticalScoreOfCell(previousVertical) +
+                                scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal),
+                              _scoreOfCell(previousVertical) +
+                                scoreGapOpenVertical(scoringScheme, seqHVal, seqVVal),
+                              TraceBitMap_<TScoreValue>::VERTICAL,
+                              TraceBitMap_<TScoreValue>::VERTICAL_OPEN,
+                              TTracebackConfig()) | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
+    // Ignore horizontal direction.
+    _horizontalScoreOfCell(current) = DPCellDefaultInfinity<DPCell_<TScoreValue, AffineGaps> >::VALUE;
+    _scoreOfCell(current) = _verticalScoreOfCell(previousVertical);
+
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        traceDir = _maxScore(_scoreOfCell(current),
+                             TraceBitMap_<TScoreValue>::NONE,
+                             _scoreOfCell(current),
+                             TraceBitMap_<TScoreValue>::NONE,
+                             traceDir,
+                             TTracebackConfig{});
+    }
+    _scoreOfCell(previousVertical) = _scoreOfCell(current);
+    return traceDir;
 }
 
 }  // namespace seqan
diff --git a/include/seqan/align/dp_formula_dynamic.h b/include/seqan/align/dp_formula_dynamic.h
index 1c8fe8b..ccd8298 100644
--- a/include/seqan/align/dp_formula_dynamic.h
+++ b/include/seqan/align/dp_formula_dynamic.h
@@ -88,7 +88,7 @@ _internalComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                       TracebackOff const &,
                       RecursionDirectionDiagonal const &)
 {
-    TScoreValue cmp = cmpGt(diagCompare, _scoreOfCell(activeCell));
+    auto cmp = cmpGt(diagCompare, _scoreOfCell(activeCell));
     activeCell._score = blend(activeCell._score, diagCompare, cmp);
     setGapExtension(activeCell, False(), False(), cmp);
     return TraceBitMap_<TScoreValue>::NONE;
@@ -121,7 +121,7 @@ _internalComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                       TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > const &,
                       RecursionDirectionDiagonal const &)
 {
-    TScoreValue cmp = cmpGt(_scoreOfCell(activeCell), diagCompare);
+    auto cmp = cmpGt(_scoreOfCell(activeCell), diagCompare);
     activeCell._score = blend(diagCompare, activeCell._score, cmp);
     setGapExtension(activeCell, False(), False(), cmp);
     return blend(TraceBitMap_<TScoreValue>::DIAGONAL | leftTrace,
@@ -159,7 +159,7 @@ _internalComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                       TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &,
                       RecursionDirectionDiagonal const &)
 {
-    TScoreValue cmp = cmpGt(diagCompare, _scoreOfCell(activeCell));
+    auto cmp = cmpGt(diagCompare, _scoreOfCell(activeCell));
     activeCell._score = blend(activeCell._score, diagCompare, cmp);
     setGapExtension(activeCell, False(), False(), cmp);
     return blend(blend(leftTrace | gapTrace,
@@ -298,7 +298,7 @@ _internalComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                       TracebackOn<TTraceConfig> const &,
                       RecursionDirectionVertical const &)
 {
-    TScoreValue cmp = isGapExtension(prevCell, DynamicGapExtensionVertical());
+    auto cmp = isGapExtension(prevCell, DynamicGapExtensionVertical());
     activeCell._score = blend(_scoreOfCell(prevCell) + scoreGapOpenVertical(score, valH, valV), activeCell._score, cmp);
     return blend(TraceBitMap_<TScoreValue>::VERTICAL_OPEN,
                  TraceBitMap_<TScoreValue>::VERTICAL,
@@ -331,7 +331,7 @@ _internalComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                       TScoreValue const & horizontalComp,
                       TracebackOff const &)
 {
-    TScoreValue cmp = cmpGt(horizontalComp, _scoreOfCell(activeCell));
+    auto cmp = cmpGt(horizontalComp, _scoreOfCell(activeCell));
     activeCell._score = blend(activeCell._score, horizontalComp, cmp);
     setGapExtension(activeCell, False(), True(), cmp);
     setGapExtension(activeCell, True(), False(), cmpEq(cmp, TraceBitMap_<TScoreValue>::NONE));
@@ -360,7 +360,7 @@ _internalComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                       TScoreValue const & horizontalComp,
                       TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> >  const &)
 {
-    TScoreValue cmp = cmpGt(horizontalComp, _scoreOfCell(activeCell));
+    auto cmp = cmpGt(horizontalComp, _scoreOfCell(activeCell));
     activeCell._score = blend(activeCell._score, horizontalComp, cmp);
     setGapExtension(activeCell, False(), True(), cmp);
     setGapExtension(activeCell, True(), False(), cmpEq(cmp, TraceBitMap_<TScoreValue>::NONE));
@@ -396,8 +396,8 @@ _internalComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                       TScoreValue const & horizontalComp,
                       TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> >  const &)
 {
-    TScoreValue cmpG = cmpGt(horizontalComp, _scoreOfCell(activeCell));
-    TScoreValue cmpE = cmpEq(horizontalComp, _scoreOfCell(activeCell));
+    auto cmpG = cmpGt(horizontalComp, _scoreOfCell(activeCell));
+    auto cmpE = cmpEq(horizontalComp, _scoreOfCell(activeCell));
     setGapExtension(activeCell, True(), False(), createVector<TScoreValue>(-1));
     setGapExtension(activeCell, False(), True(), cmpG);
     setGapExtension(activeCell, True(), True(), cmpE);
@@ -413,25 +413,30 @@ _internalComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore                 [RecursionAllDirection, DynamicGaps]
+// Function _computeScore                 [RecursionAllDirection, DynamicGaps]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, DynamicGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, DynamicGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionAll const &,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
+              DPCell_<TScoreValue, DynamicGaps> & previousDiagonal,
+              DPCell_<TScoreValue, DynamicGaps> const & previousHorizontal,
+              DPCell_<TScoreValue, DynamicGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionAll const &,
+              DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig, TExecPolicy> const &)
 {
     typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-    typedef typename std::decay<decltype(activeCell)>::type TCell;
+    typedef DPCell_<TScoreValue, DynamicGaps> TCell;
 
+    // Compute intermediate diagonal result.
+    TScoreValue intermediate = static_cast<TScoreValue>(_scoreOfCell(previousDiagonal) +
+                                                        score(scoringScheme, seqHVal, seqVVal));
+    // Cache previous Diagonal
+    _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal);
     // Compute best alignment from either horizontal open or extension.
     TCell tmpScore(_scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal));
     TTraceValue tvGap = _internalComputeScore(tmpScore, previousHorizontal, seqHVal, seqVVal, scoringScheme,
@@ -444,61 +449,45 @@ _doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
 
     // Finds the maximum between the vertical and the horizontal matrix. Stores the flag for coming from a potential direction.
     TTraceValue tvMax = _internalComputeScore(activeCell, tmpScore._score, TTracebackConfig());  // Stores from where the maximal score comes.
-    tmpScore._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell, tmpScore._score, tvGap, tvMax, TTracebackConfig(), RecursionDirectionDiagonal());
-}
+    tmpScore._score = intermediate;
+    tvMax = _internalComputeScore(activeCell, tmpScore._score, tvGap, tvMax, TTracebackConfig(), RecursionDirectionDiagonal());
 
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, DynamicGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, DynamicGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionAll const &,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
-{
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-    typedef typename std::decay<decltype(activeCell)>::type TCell;
-
-    // Compute best alignment from either horizontal open or extension.
-    TCell tmpScore = {_scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal),
-                      typename TCell::TFlagMaskType()};
-    TTraceValue tvGap = _internalComputeScore(tmpScore, previousHorizontal, seqHVal, seqVVal, scoringScheme,
-                                              TTracebackConfig(), RecursionDirectionHorizontal());
-
-    // Compute best alignment between vertical and vertical open gap.
-    activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-    tvGap |= _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme,
-                                   TTracebackConfig(), RecursionDirectionVertical());
-
-    // Finds the maximum between the vertical and the horizontal matrix. Stores the flag for coming from a potential direction.
-    TTraceValue tvMax = _internalComputeScore(activeCell, tmpScore._score, TTracebackConfig());  // Stores from where the maximal score comes.
-    tmpScore._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell, tmpScore._score, tvGap, tvMax, TTracebackConfig(), RecursionDirectionDiagonal());
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tvMax = _maxScore(_scoreOfCell(activeCell),
+                          TraceBitMap_<TScoreValue>::NONE,
+                          _scoreOfCell(activeCell),
+                          TraceBitMap_<TScoreValue>::NONE,
+                          tvMax,
+                          TTracebackConfig{});
+    }
+    previousVertical = activeCell;
+    return tvMax;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore       [RecursionUpperDiagonalDirection, DynamicGaps]
+// Function _computeScore       [RecursionUpperDiagonalDirection, DynamicGaps]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, DynamicGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionUpperDiagonal const &,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
+              DPCell_<TScoreValue, DynamicGaps> & previousDiagonal,
+              DPCell_<TScoreValue, DynamicGaps> const & previousHorizontal,
+              DPCell_<TScoreValue, DynamicGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionUpperDiagonal const &,
+              DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig, TExecPolicy> const &)
 {
     typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
+    // Compute intermediate diagonal result.
+    TScoreValue intermediate = static_cast<TScoreValue>(_scoreOfCell(previousDiagonal) +
+                                                        score(scoringScheme, seqHVal, seqVVal));
+    // Cache previous Diagonal
+    _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal);
 
     // This computes the difference between the horizontal extend and horizontal open.
     activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
@@ -506,58 +495,38 @@ _doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                                            TTracebackConfig(), RecursionDirectionHorizontal());
 
     setGapExtension(activeCell, False(), True());
-    TScoreValue tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell, tmpScore, tv, TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
-                                 TTracebackConfig(),RecursionDirectionDiagonal());
-}
-
-
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, DynamicGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionUpperDiagonal const &,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
-{
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-
-    // This computes the difference between the horizontal extend and horizontal open.
-    activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
-    TTraceValue tv = _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme,
-                                           TTracebackConfig(), RecursionDirectionHorizontal());
+    tv = _internalComputeScore(activeCell, intermediate, tv, TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
+                               TTracebackConfig(),RecursionDirectionDiagonal());
 
-    setGapExtension(activeCell, False(), True(), createVector<TScoreValue>(-1));
-    TScoreValue tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell,
-                                 tmpScore,
-                                 tv,
-                                 TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
-                                 TTracebackConfig(),
-                                 RecursionDirectionDiagonal());
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    previousVertical = activeCell;
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore      [RecursionDirectionLowerDiagonal, DynamicGaps]
+// Function _computeScore      [RecursionDirectionLowerDiagonal, DynamicGaps]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, DynamicGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionLowerDiagonal const &,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
+              DPCell_<TScoreValue, DynamicGaps> const & previousDiagonal,
+              DPCell_<TScoreValue, DynamicGaps> const & /*previousHorizontal*/,
+              DPCell_<TScoreValue, DynamicGaps> const & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionLowerDiagonal const &,
+              DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig, TExecPolicy> const &)
 {
     typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
 
@@ -567,121 +536,137 @@ _doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
                                            TTracebackConfig(), RecursionDirectionVertical());
     setGapExtension(activeCell, True(), False());
     TScoreValue tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell, tmpScore, tv, TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
+    tv = _internalComputeScore(activeCell, tmpScore, tv, TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
                                  TTracebackConfig(), RecursionDirectionDiagonal());
-}
-
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, DynamicGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionLowerDiagonal const &,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
-{
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-
-    // This computes the difference between the vertical extend and vertical open.
-    activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-    TTraceValue tv = _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme,
-                                           TTracebackConfig(), RecursionDirectionVertical());
-    setGapExtension(activeCell, True(), False(), createVector<TScoreValue>(-1));
-    TScoreValue tmpScore = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell,
-                                 tmpScore,
-                                 tv,
-                                 TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
-                                 TTracebackConfig(),
-                                 RecursionDirectionDiagonal());
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore                      [RecursionHorizontalDirection]
+// Function _computeScore                      [RecursionHorizontalDirection]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, DynamicGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionHorizontal const & tag,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
+              DPCell_<TScoreValue, DynamicGaps> & previousDiagonal,
+              DPCell_<TScoreValue, DynamicGaps> const previousHorizontal,  // NOTE(rrahn): We want the copy here. Don't change!!!
+              DPCell_<TScoreValue, DynamicGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionHorizontal const & tag,
+              DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig, TExecPolicy> const &)
 {
+    // Cache previous diagonal value.
+    _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal);
     activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
     setGapExtension(activeCell, False(), True());
-    return _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme,
-                                 TTracebackConfig(), tag) | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
+    auto tv = _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme,
+                                    TTracebackConfig(), tag) | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
+    previousVertical = activeCell;
+    return tv;
 }
 
+// NOTE(rrahn): Here we copy the previousCellHorizontal as it might refer to the same value as acticeCell.
+// Since we cannot assure here to read the value before we write it, we have to take a copy from it.
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, DynamicGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionHorizontal const & tag,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
+_computeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
+              DPCell_<TScoreValue, DynamicGaps> & previousDiagonal,
+              DPCell_<TScoreValue, DynamicGaps> const previousHorizontal, // NOTE(rrahn): Don't change!!!
+              DPCell_<TScoreValue, DynamicGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionHorizontal const & tag,
+              DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig, TExecPolicy> const &)
 {
+    // Cache previous diagonal value.
+    _scoreOfCell(previousDiagonal) = _scoreOfCell(previousHorizontal);
     activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
     setGapExtension(activeCell, False(), True(), createVector<TScoreValue>(-1));
-    return _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme,
+    auto tv = _internalComputeScore(activeCell, previousHorizontal, seqHVal, seqVVal, scoringScheme,
                                  TTracebackConfig(), tag) | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
+    previousVertical = activeCell;
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore                        [RecursionVerticalDirection]
+// Function _computeScore                        [RecursionVerticalDirection]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, DynamicGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionVertical const & tag,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
+inline typename TraceBitMap_<TScoreValue>::Type
+_computeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
+              DPCell_<TScoreValue, DynamicGaps> & /*previousDiagonal*/,
+              DPCell_<TScoreValue, DynamicGaps> const & /*previousHorizontal*/,
+              DPCell_<TScoreValue, DynamicGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionVertical const & tag,
+              DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig, TExecPolicy> const &)
 {
     activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
     setGapExtension(activeCell, True(), False());
-    return _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme,
+    auto tv = _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme,
                                  TTracebackConfig(), tag) | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
+    previousVertical = activeCell;
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    return tv;
 }
 
-template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_doComputeScore(DPCell_<TScoreValue, DynamicGaps> & activeCell,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, DynamicGaps> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, DynamicGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionVertical const & tag,
-                DPProfile_<TAlgorithm, DynamicGaps, TTracebackConfig> const &)
+// Independent of gap cost model.
+template <typename TScoreValue,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TAlgoTag, typename TTraceFlag, typename TExecPolicy>
+inline auto
+_computeScore(DPCell_<TScoreValue, DynamicGaps> & current,
+              DPCell_<TScoreValue, DynamicGaps> & cacheDiagonal,
+              DPCell_<TScoreValue, DynamicGaps> const & /*cacheHorizontal*/,
+              DPCell_<TScoreValue, DynamicGaps> & cacheVertical,
+              TSequenceHValue const & /*seqHVal*/,
+              TSequenceVValue const & /*seqVVal*/,
+              TScoringScheme const & /*scoringScheme*/,
+              RecursionDirectionZero const &,
+              DPProfile_<TAlgoTag, DynamicGaps, TTraceFlag, TExecPolicy> const &)
 {
-    activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-    setGapExtension(activeCell, True(), False(), createVector<TScoreValue>(-1));
-    return _internalComputeScore(activeCell, previousVertical, seqHVal, seqVVal, scoringScheme,
-                                 TTracebackConfig(), tag) | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
+    _scoreOfCell(current) = TraceBitMap_<TScoreValue>::NONE;
+    setGapExtension(current, False(), False());
+    _scoreOfCell(cacheDiagonal) = _scoreOfCell(current);
+    cacheVertical = current;
+    return TraceBitMap_<TScoreValue>::NONE;
 }
 
 }  // namespace seqan
diff --git a/include/seqan/align/dp_formula_linear.h b/include/seqan/align/dp_formula_linear.h
index 45ed936..be33364 100644
--- a/include/seqan/align/dp_formula_linear.h
+++ b/include/seqan/align/dp_formula_linear.h
@@ -56,234 +56,200 @@ namespace seqan {
 // ============================================================================
 
 // ----------------------------------------------------------------------------
-// Function _internalComputeScore()
-// ----------------------------------------------------------------------------
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL,
-                      TTraceValueR,
-                      TracebackOff const &)
-{
-    if (activeCell._score < rightCompare)
-        activeCell._score = rightCompare;
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL,
-                      TTraceValueR,
-                      TracebackOff const &)
-{
-    TScoreValue cmp = cmpGt(rightCompare, activeCell._score);
-    activeCell._score = blend(activeCell._score, rightCompare, cmp);
-    return TraceBitMap_<TScoreValue>::NONE;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueR rightTrace,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > const &)
-{
-    if (activeCell._score < rightCompare)
-    {
-        activeCell._score = rightCompare;
-        return rightTrace;
-    }
-    return leftTrace;
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL const & leftTrace,
-                      TTraceValueR const & rightTrace,
-                      TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > const &)
-{
-    TScoreValue cmp = cmpGt(rightCompare, activeCell._score);
-    activeCell._score = blend(activeCell._score, rightCompare, cmp);
-    return blend(leftTrace, rightTrace, cmp);
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-    inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TScoreValue> > >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL leftTrace,
-                      TTraceValueR rightTrace,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> > const &)
-{
-    if (activeCell._score < rightCompare)
-    {
-        activeCell._score = rightCompare;
-        return rightTrace;
-    }
-    return (activeCell._score == rightCompare) ? (rightTrace | leftTrace) : (leftTrace);
-}
-
-template <typename TScoreValue, typename TTraceValueL, typename TTraceValueR, typename TGapsPlacement>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TScoreValue> >, typename TraceBitMap_<TScoreValue>::Type)
-_internalComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                      TScoreValue const & rightCompare,
-                      TTraceValueL const & leftTrace,
-                      TTraceValueR const & rightTrace,
-                      TracebackOn<TracebackConfig_<CompleteTrace, TGapsPlacement> > const &)
-{
-    // Check for greater values.
-    TScoreValue cmp = cmpGt(activeCell._score, rightCompare);  // cmp greater
-    activeCell._score = blend(rightCompare, activeCell._score, cmp);  // activeCell._score
-
-    // Check for equality.
-    return blend(blend(rightTrace, leftTrace, cmp), leftTrace | rightTrace, cmpEq(rightCompare, activeCell._score));
-}
-
-// ----------------------------------------------------------------------------
-// Function _doComputeScore                 [RecursionDirectionAll, LinearGaps]
+// Function _computeScore                 [RecursionDirectionAll, LinearGaps]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
 inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                DPCell_<TScoreValue, LinearGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, LinearGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, LinearGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionAll const &,
-                DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig> const &)
+_computeScore(DPCell_<TScoreValue, LinearGaps> & current,
+              DPCell_<TScoreValue, LinearGaps> & previousDiagonal,
+              DPCell_<TScoreValue, LinearGaps> const & previousHorizontal,
+              DPCell_<TScoreValue, LinearGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionAll const &,
+              DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    typedef typename TraceBitMap_<TScoreValue>::Type TTraceValue;
-    activeCell._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-
-    TScoreValue tmpScore = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-
-    TTraceValue tv = _internalComputeScore(activeCell,
-                                           tmpScore,
-                                           TraceBitMap_<TScoreValue>::DIAGONAL,
-                                           TraceBitMap_<TScoreValue>::VERTICAL | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
-                                           TTracebackConfig());
-    tmpScore = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell,
-                                 tmpScore,
-                                 tv,
-                                 TraceBitMap_<TScoreValue>::HORIZONTAL | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
-                                 TTracebackConfig());
+    // Cache next diagonal.
+    auto intermediate = static_cast<TScoreValue>(_scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal));
+    previousDiagonal = _scoreOfCell(previousHorizontal);
+
+    auto tv = _maxScore(_scoreOfCell(current),
+                        _scoreOfCell(previousVertical)+
+                            scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal),
+                        _scoreOfCell(previousHorizontal) +
+                            scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal),
+                        TraceBitMap_<TScoreValue>::VERTICAL | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
+                        TraceBitMap_<TScoreValue>::HORIZONTAL | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
+                        TTracebackConfig{});
+    // Compute the intermediate value.
+    tv = _maxScore(_scoreOfCell(current),
+                   intermediate,
+                   _scoreOfCell(current),
+                   TraceBitMap_<TScoreValue>::DIAGONAL,
+                   tv,
+                   TTracebackConfig());
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    previousVertical = current;
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore       [RecursionDirectionUpperDiagonal, LinearGaps]
+// Function _computeScore       [RecursionDirectionUpperDiagonal, LinearGaps]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
 inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                DPCell_<TScoreValue, LinearGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, LinearGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, LinearGaps> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionUpperDiagonal const &,
-                DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig> const &)
+_computeScore(DPCell_<TScoreValue, LinearGaps> & current,
+              DPCell_<TScoreValue, LinearGaps> & previousDiagonal,
+              DPCell_<TScoreValue, LinearGaps> const & previousHorizontal,
+              DPCell_<TScoreValue, LinearGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionUpperDiagonal const &,
+              DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    activeCell._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    TScoreValue tmpScore = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
-    return _internalComputeScore(activeCell,
-                                 tmpScore,
-                                 TraceBitMap_<TScoreValue>::DIAGONAL,
-                                 TraceBitMap_<TScoreValue>::HORIZONTAL | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
-                                 TTracebackConfig());
+    // Precalculate diagonal direction.
+    auto intermediate = static_cast<TScoreValue>(_scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal));
+    // Cache next diagonal value.
+    previousDiagonal = _scoreOfCell(previousHorizontal);
+
+    auto tv = _maxScore(_scoreOfCell(current),
+                        intermediate,
+                        _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal),
+                        TraceBitMap_<TScoreValue>::DIAGONAL,
+                        TraceBitMap_<TScoreValue>::HORIZONTAL | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX,
+                        TTracebackConfig());
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    previousVertical = current;
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore       [RecursionDirectionLowerDiagonal, LinearGaps]
+// Function _computeScore       [RecursionDirectionLowerDiagonal, LinearGaps]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
 inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                DPCell_<TScoreValue, LinearGaps> const & previousDiagonal,
-                DPCell_<TScoreValue, LinearGaps> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, LinearGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionLowerDiagonal const &,
-                DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig> const &)
+_computeScore(DPCell_<TScoreValue, LinearGaps> & current,
+              DPCell_<TScoreValue, LinearGaps> const & previousDiagonal,
+              DPCell_<TScoreValue, LinearGaps> const & /*previousHorizontal*/,
+              DPCell_<TScoreValue, LinearGaps> const & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionLowerDiagonal const &,
+              DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    activeCell._score = _scoreOfCell(previousDiagonal) + score(scoringScheme, seqHVal, seqVVal);
-    TScoreValue tmpScore = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-
-    return _internalComputeScore(activeCell,
-                                 tmpScore,
-                                 TraceBitMap_<TScoreValue>::DIAGONAL,
-                                 TraceBitMap_<TScoreValue>::VERTICAL | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
-                                 TTracebackConfig());
+    auto tv  = _maxScore(_scoreOfCell(current),
+                         static_cast<TScoreValue>(_scoreOfCell(previousDiagonal) +
+                                              score(scoringScheme, seqHVal, seqVVal)),
+                         static_cast<TScoreValue>(_scoreOfCell(previousVertical) +
+                                              scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal)),
+                         TraceBitMap_<TScoreValue>::DIAGONAL,
+                         TraceBitMap_<TScoreValue>::VERTICAL | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX,
+                         TTracebackConfig());
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore                      [RecursionDirectionHorizontal]
+// Function _computeScore                      [RecursionDirectionHorizontal]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
 inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                DPCell_<TScoreValue, LinearGaps> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, LinearGaps> const & previousHorizontal,
-                DPCell_<TScoreValue, LinearGaps> const & /*previousVertical*/,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionHorizontal const &,
-                DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig> const &)
+_computeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
+              DPCell_<TScoreValue, LinearGaps> & previousDiagonal,
+              DPCell_<TScoreValue, LinearGaps> const & previousHorizontal,
+              DPCell_<TScoreValue, LinearGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionHorizontal const &,
+              DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    activeCell._score = _scoreOfCell(previousHorizontal) + scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
-
-    if (!IsTracebackEnabled_<TTracebackConfig>::VALUE)
-        return TraceBitMap_<TScoreValue>::NONE;
-
-    return TraceBitMap_<TScoreValue>::HORIZONTAL
-                | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
+    // Cache previous diagonal.
+    previousDiagonal = previousHorizontal;
+    // Compute current value.
+    _scoreOfCell(activeCell) = _scoreOfCell(previousHorizontal) +
+                               scoreGapExtendHorizontal(scoringScheme, seqHVal, seqVVal);
+    auto tv = TraceBitMap_<TScoreValue>::HORIZONTAL | TraceBitMap_<TScoreValue>::MAX_FROM_HORIZONTAL_MATRIX;
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(activeCell),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    // Cache next vertical.
+    previousVertical = activeCell;
+    return tv;
 }
 
 // ----------------------------------------------------------------------------
-// Function _doComputeScore                        [RecursionDirectionVertical]
+// Function _computeScore                        [RecursionDirectionVertical]
 // ----------------------------------------------------------------------------
 
 template <typename TScoreValue, typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme,
-          typename TAlgorithm, typename TTracebackConfig>
+          typename TAlgorithm, typename TTracebackConfig, typename TExecPolicy>
 inline typename TraceBitMap_<TScoreValue>::Type
-_doComputeScore(DPCell_<TScoreValue, LinearGaps> & activeCell,
-                DPCell_<TScoreValue, LinearGaps> const & /*previousDiagonal*/,
-                DPCell_<TScoreValue, LinearGaps> const & /*previousHorizontal*/,
-                DPCell_<TScoreValue, LinearGaps> const & previousVertical,
-                TSequenceHValue const & seqHVal,
-                TSequenceVValue const & seqVVal,
-                TScoringScheme const & scoringScheme,
-                RecursionDirectionVertical const &,
-                DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig> const &)
+_computeScore(DPCell_<TScoreValue, LinearGaps> & current,
+              DPCell_<TScoreValue, LinearGaps> const & /*previousDiagonal*/,
+              DPCell_<TScoreValue, LinearGaps> const & /*previousHorizontal*/,
+              DPCell_<TScoreValue, LinearGaps> & previousVertical,
+              TSequenceHValue const & seqHVal,
+              TSequenceVValue const & seqVVal,
+              TScoringScheme const & scoringScheme,
+              RecursionDirectionVertical const &,
+              DPProfile_<TAlgorithm, LinearGaps, TTracebackConfig, TExecPolicy> const &)
 {
-    activeCell._score = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
-
-    if (!IsTracebackEnabled_<TTracebackConfig>::VALUE)
-        return TraceBitMap_<TScoreValue>::NONE;
-
-    return TraceBitMap_<TScoreValue>::VERTICAL
-                | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
+    _scoreOfCell(current) = _scoreOfCell(previousVertical) + scoreGapExtendVertical(scoringScheme, seqHVal, seqVVal);
+    auto tv = TraceBitMap_<TScoreValue>::VERTICAL | TraceBitMap_<TScoreValue>::MAX_FROM_VERTICAL_MATRIX;
+    if (IsLocalAlignment_<TAlgorithm>::VALUE)
+    {
+        tv = _maxScore(_scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       _scoreOfCell(current),
+                       TraceBitMap_<TScoreValue>::NONE,
+                       tv,
+                       TTracebackConfig{});
+    }
+    // Cache previous vertical.
+    previousVertical = current;
+    return tv;
 }
 
 }  // namespace seqan
diff --git a/include/seqan/align/dp_matrix.h b/include/seqan/align/dp_matrix.h
index 1e853c5..9ed19bb 100644
--- a/include/seqan/align/dp_matrix.h
+++ b/include/seqan/align/dp_matrix.h
@@ -100,21 +100,21 @@ struct DPMatrixDimension_
 // ----------------------------------------------------------------------------
 
 // The dp matrix used as a score matrix and as a trace-back matrix.
-template <typename TValue, typename TMatrixSpec>
+template <typename TValue, typename TMatrixSpec, typename THost = String<TValue> >
 class DPMatrix_
 {};
 
 
 // Default dp matrix implementation stores all cells of the dp matrix in the
 // underlying two-dimensional matrix.
-template <typename TValue>
-class DPMatrix_<TValue, FullDPMatrix>
+template <typename TValue, typename THost>
+class DPMatrix_<TValue, FullDPMatrix, THost>
 {
 public:
 
-    typedef typename Member<DPMatrix_, DPMatrixMember>::Type THost;
+    typedef typename Member<DPMatrix_, DPMatrixMember>::Type TMatrix;
 
-    Holder<THost>   data_host;  // The host containing the actual matrix.
+    Holder<TMatrix>   data_host;  // The host containing the actual matrix.
 
     DPMatrix_() :
         data_host()
@@ -151,16 +151,16 @@ struct DefaultScoreMatrixSpec_<LocalAlignment_<WatermanEggert> >
 // ----------------------------------------------------------------------------
 
 // Returns the type of the underlying matrix.
-template <typename TValue, typename TMatrixSpec>
-struct Member<DPMatrix_<TValue, TMatrixSpec>, DPMatrixMember>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Member<DPMatrix_<TValue, TMatrixSpec, THost>, DPMatrixMember>
 {
-    typedef Matrix<TValue, 2> Type;
+    typedef Matrix<TValue, 2, THost> Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct Member<DPMatrix_<TValue, TMatrixSpec> const, DPMatrixMember>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Member<DPMatrix_<TValue, TMatrixSpec, THost> const, DPMatrixMember>
 {
-    typedef Matrix<TValue, 2> const Type;
+    typedef Matrix<TValue, 2, THost> const Type;
 };
 
 // ----------------------------------------------------------------------------
@@ -172,18 +172,18 @@ struct Member<DPMatrix_<TValue, TMatrixSpec> const, DPMatrixMember>
 template <typename TDPMatrix>
 struct SizeArr_ {};
 
-template <typename TValue, typename TMatrixSpec>
-struct SizeArr_<DPMatrix_<TValue, TMatrixSpec> >
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct SizeArr_<DPMatrix_<TValue, TMatrixSpec, THost> >
 {
-    typedef DPMatrix_<TValue, TMatrixSpec> TDPMatrix_;
+    typedef DPMatrix_<TValue, TMatrixSpec, THost> TDPMatrix_;
     typedef typename Member<TDPMatrix_, DPMatrixMember>::Type TDataHost_;
     typedef typename SizeArr_<TDataHost_>::Type Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct SizeArr_<DPMatrix_<TValue, TMatrixSpec> const>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct SizeArr_<DPMatrix_<TValue, TMatrixSpec, THost> const>
 {
-    typedef DPMatrix_<TValue, TMatrixSpec> TDPMatrix_;
+    typedef DPMatrix_<TValue, TMatrixSpec, THost> TDPMatrix_;
     typedef typename Member<TDPMatrix_, DPMatrixMember>::Type TDataHost_;
     typedef typename SizeArr_<TDataHost_>::Type const Type;
 };
@@ -192,109 +192,59 @@ struct SizeArr_<DPMatrix_<TValue, TMatrixSpec> const>
 // Metafunction Spec
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
-struct Spec<DPMatrix_<TValue, TMatrixSpec> >
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Spec<DPMatrix_<TValue, TMatrixSpec, THost> >
 {
     typedef TMatrixSpec Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct Spec<DPMatrix_<TValue, TMatrixSpec> const>:
-    Spec<DPMatrix_<TValue, TMatrixSpec> >{};
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Spec<DPMatrix_<TValue, TMatrixSpec, THost> const>:
+    Spec<DPMatrix_<TValue, TMatrixSpec, THost> >{};
 
 
 // ----------------------------------------------------------------------------
 // Metafunction Value
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
-struct Value<DPMatrix_<TValue, TMatrixSpec> >
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Value<DPMatrix_<TValue, TMatrixSpec, THost> >
 {
     typedef TValue Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct Value<DPMatrix_<TValue, TMatrixSpec> const>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Value<DPMatrix_<TValue, TMatrixSpec, THost> const>
 {
     typedef TValue const Type;
 };
 
 // ----------------------------------------------------------------------------
-// Metafunction Reference
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TMatrixSpec>
-struct Reference<DPMatrix_<TValue, TMatrixSpec> >
-{
-    typedef TValue & Type;
-};
-
-template <typename TValue, typename TMatrixSpec>
-struct Reference<DPMatrix_<TValue, TMatrixSpec> const>
-{
-    typedef TValue const & Type;
-};
-
-// ----------------------------------------------------------------------------
-// Metafunction GetValue
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TMatrixSpec>
-struct GetValue<DPMatrix_<TValue, TMatrixSpec> >:
-    Reference<DPMatrix_<TValue, TMatrixSpec> >{};
-
-template <typename TValue, typename TMatrixSpec>
-struct GetValue<DPMatrix_<TValue, TMatrixSpec> const>:
-    Reference<DPMatrix_<TValue, TMatrixSpec> const>{};
-
-// ----------------------------------------------------------------------------
-// Metafunction Position
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TMatrixSpec>
-struct Position<DPMatrix_<TValue, TMatrixSpec> >
-{
-    typedef typename DPMatrix_<TValue, TMatrixSpec>::THost TDataMatrix_;
-    typedef typename Position<TDataMatrix_>::Type Type;
-};
-
-template <typename TValue, typename TMatrixSpec>
-struct Position<DPMatrix_<TValue, TMatrixSpec> const>:
-    Position<DPMatrix_<TValue, TMatrixSpec> >{};
-
-// ----------------------------------------------------------------------------
 // Metafunction Size
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
-struct Size<DPMatrix_<TValue, TMatrixSpec> >
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Size<DPMatrix_<TValue, TMatrixSpec, THost> >
 {
-    typedef typename DPMatrix_<TValue, TMatrixSpec>::THost TDataMatrix_;
+    typedef typename DPMatrix_<TValue, TMatrixSpec, THost>::TMatrix TDataMatrix_;
     typedef typename Size<TDataMatrix_>::Type Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct Size<DPMatrix_<TValue, TMatrixSpec> const>:
-    Size<DPMatrix_<TValue, TMatrixSpec> >{};
 
 // ----------------------------------------------------------------------------
 // Metafunction Host
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
-struct Host<DPMatrix_<TValue, TMatrixSpec> >
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Host<DPMatrix_<TValue, TMatrixSpec, THost> >
 {
-    typedef DPMatrix_<TValue, TMatrixSpec> TDPMatrix_;
-    typedef typename Member<TDPMatrix_, DPMatrixMember>::Type TDataMatrix_;
-    typedef typename Host<TDataMatrix_>::Type Type;
+    typedef THost Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct Host<DPMatrix_<TValue, TMatrixSpec> const>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Host<DPMatrix_<TValue, TMatrixSpec, THost> const>
 {
-    typedef DPMatrix_<TValue, TMatrixSpec> TDPMatrix_;
-    typedef typename Member<TDPMatrix_, DPMatrixMember>::Type TDataMatrix_;
-    typedef typename Host<TDataMatrix_>::Type const Type;
+    typedef THost const Type;
 };
 
 // ----------------------------------------------------------------------------
@@ -305,34 +255,34 @@ struct Host<DPMatrix_<TValue, TMatrixSpec> const>
 // non-rooted iterator to the underlying vector of the hosted two-dimensional
 // matrix. The rooted iterator returns the iterator defined by the
 // hosted matrix object which is a position iterator.
-template <typename TValue, typename TMatrixSpec>
-struct Iterator<DPMatrix_<TValue, TMatrixSpec>, Standard const>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Iterator<DPMatrix_<TValue, TMatrixSpec, THost>, Standard>
 {
-    typedef DPMatrix_<TValue, TMatrixSpec> TDPMatrix_;
+    typedef DPMatrix_<TValue, TMatrixSpec, THost> TDPMatrix_;
     typedef typename  Host<TDPMatrix_>::Type THost_;
     typedef typename Iterator<THost_, Standard>::Type Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct Iterator<DPMatrix_<TValue, TMatrixSpec> const, Standard const>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Iterator<DPMatrix_<TValue, TMatrixSpec, THost> const, Standard>
 {
-    typedef DPMatrix_<TValue, TMatrixSpec> const TDPMatrix_;
+    typedef DPMatrix_<TValue, TMatrixSpec, THost> const TDPMatrix_;
     typedef typename  Host<TDPMatrix_>::Type THost_;
     typedef typename Iterator<THost_ const, Standard>::Type Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct Iterator<DPMatrix_<TValue, TMatrixSpec>, Rooted const>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Iterator<DPMatrix_<TValue, TMatrixSpec, THost>, Rooted>
 {
-    typedef DPMatrix_<TValue, TMatrixSpec> TDPMatrix_;
+    typedef DPMatrix_<TValue, TMatrixSpec, THost> TDPMatrix_;
     typedef typename Member<TDPMatrix_, DPMatrixMember>::Type TDataMatrix_;
     typedef typename Iterator<TDataMatrix_, Rooted>::Type Type;
 };
 
-template <typename TValue, typename TMatrixSpec>
-struct Iterator<DPMatrix_<TValue, TMatrixSpec> const, Rooted const>
+template <typename TValue, typename TMatrixSpec, typename THost>
+struct Iterator<DPMatrix_<TValue, TMatrixSpec, THost> const, Rooted>
 {
-    typedef DPMatrix_<TValue, TMatrixSpec> TDPMatrix_;
+    typedef DPMatrix_<TValue, TMatrixSpec, THost> TDPMatrix_;
     typedef typename Member<TDPMatrix_, DPMatrixMember>::Type TDataMatrix_;
     typedef typename Iterator<TDataMatrix_ const, Rooted>::Type Type;
 };
@@ -356,16 +306,16 @@ inline bool _checkCorrectDimension(DPMatrixDimension_::TValue dim)
 // ----------------------------------------------------------------------------
 
 // Returns a reference to the hosted matrix.
-template <typename TValue, typename TMatrixSpec>
-inline Holder<typename Host<DPMatrix_<TValue, TMatrixSpec> >::Type> &
-_dataHost(DPMatrix_<TValue, TMatrixSpec>& dpMatrix)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline Holder<typename Host<DPMatrix_<TValue, TMatrixSpec, THost> >::Type> &
+_dataHost(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix)
 {
     return _dataHost(value(dpMatrix.data_host));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline Holder<typename Host<DPMatrix_<TValue, TMatrixSpec> >::Type> const &
-_dataHost(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline Holder<typename Host<DPMatrix_<TValue, TMatrixSpec, THost> >::Type> const &
+_dataHost(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix)
 {
     return _dataHost(value(dpMatrix.data_host));
 }
@@ -375,16 +325,16 @@ _dataHost(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
 // ----------------------------------------------------------------------------
 
 // Returns a reference to the _dataLengths container of the hosted matrix.
-template <typename TValue, typename TMatrixSpec>
-inline typename SizeArr_<DPMatrix_<TValue, TMatrixSpec> >::Type &
-_dataLengths(DPMatrix_<TValue, TMatrixSpec>&dpMatrix)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename SizeArr_<DPMatrix_<TValue, TMatrixSpec, THost> >::Type &
+_dataLengths(DPMatrix_<TValue, TMatrixSpec, THost>&dpMatrix)
 {
     return _dataLengths(value(dpMatrix.data_host));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline typename SizeArr_<DPMatrix_<TValue, TMatrixSpec> const>::Type &
-_dataLengths(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename SizeArr_<DPMatrix_<TValue, TMatrixSpec, THost> const>::Type &
+_dataLengths(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix)
 {
     return _dataLengths(value(dpMatrix.data_host));
 }
@@ -394,16 +344,16 @@ _dataLengths(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
 // ----------------------------------------------------------------------------
 
 // Returns a reference to the _dataFactors container of the hosted matrix.
-template <typename TValue, typename TMatrixSpec>
-inline typename SizeArr_<DPMatrix_<TValue, TMatrixSpec> >::Type &
-_dataFactors(DPMatrix_<TValue, TMatrixSpec>&dpMatrix)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename SizeArr_<DPMatrix_<TValue, TMatrixSpec, THost> >::Type &
+_dataFactors(DPMatrix_<TValue, TMatrixSpec, THost>&dpMatrix)
 {
     return _dataFactors(value(dpMatrix.data_host));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline typename SizeArr_<DPMatrix_<TValue, TMatrixSpec> const>::Type &
-_dataFactors(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename SizeArr_<DPMatrix_<TValue, TMatrixSpec, THost> const>::Type &
+_dataFactors(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix)
 {
     return _dataFactors(value(dpMatrix.data_host));
 }
@@ -413,35 +363,35 @@ _dataFactors(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
 // ----------------------------------------------------------------------------
 
 // Returns the value of the matrix at the given host position.
-template <typename TValue, typename TMatrixSpec, typename TPosition>
-inline typename Reference<DPMatrix_<TValue, TMatrixSpec> >::Type
-value(DPMatrix_<TValue, TMatrixSpec> & dpMatrix,
+template <typename TValue, typename TMatrixSpec, typename THost, typename TPosition>
+inline typename Reference<DPMatrix_<TValue, TMatrixSpec, THost> >::Type
+value(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix,
       TPosition const & pos)
 {
     return value(value(dpMatrix.data_host), pos);
 }
 
-template <typename TValue, typename TMatrixSpec, typename TPosition>
-inline typename Reference<DPMatrix_<TValue, TMatrixSpec> const>::Type
-value(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix,
+template <typename TValue, typename TMatrixSpec, typename THost, typename TPosition>
+inline typename Reference<DPMatrix_<TValue, TMatrixSpec, THost> const>::Type
+value(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix,
       TPosition const & pos)
 {
     return value(value(dpMatrix.data_host), pos);
 }
 
 // Returns the value of the matrix at the two given coordinates.
-template <typename TValue, typename TMatrixSpec, typename TPositionV, typename TPositionH>
-inline typename Reference<DPMatrix_<TValue, TMatrixSpec> >::Type
-value(DPMatrix_<TValue, TMatrixSpec> & dpMatrix,
+template <typename TValue, typename TMatrixSpec, typename THost, typename TPositionV, typename TPositionH>
+inline typename Reference<DPMatrix_<TValue, TMatrixSpec, THost> >::Type
+value(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix,
       TPositionV const & posDimV,
       TPositionH const & posDimH)
 {
     return value(value(dpMatrix.data_host), posDimV, posDimH);
 }
 
-template <typename TValue, typename TMatrixSpec, typename TPositionV, typename TPositionH>
-inline typename Reference<DPMatrix_<TValue, TMatrixSpec> const>::Type
-value(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix,
+template <typename TValue, typename TMatrixSpec, typename THost, typename TPositionV, typename TPositionH>
+inline typename Reference<DPMatrix_<TValue, TMatrixSpec, THost> const>::Type
+value(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix,
       TPositionV const & posDimV,
       TPositionH const & posDimH)
 {
@@ -453,9 +403,9 @@ value(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix,
 // ----------------------------------------------------------------------------
 
 // Returns the length of a given dimension.
-template <typename TValue, typename TMatrixSpec>
-inline typename Size<DPMatrix_<TValue, TMatrixSpec> const>::Type
-length(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix,
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Size<DPMatrix_<TValue, TMatrixSpec, THost> const>::Type
+length(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix,
        unsigned int dimension)
 {
     SEQAN_ASSERT(_checkCorrectDimension(dimension));
@@ -464,9 +414,9 @@ length(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix,
 }
 
 // Returns the overall length of the underlying vector of the hosted matrix.
-template <typename TValue, typename TMatrixSpec>
-inline typename Size<DPMatrix_<TValue, TMatrixSpec> const>::Type
-length(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Size<DPMatrix_<TValue, TMatrixSpec, THost> const>::Type
+length(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix)
 {
     return length(value(dpMatrix.data_host));  // Note that even if the dimensional lengths are set but the matrix was not resized
     // this function returns 0 or the previous length of the host before the resize.
@@ -476,9 +426,9 @@ length(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
 // Function clear()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
+template <typename TValue, typename TMatrixSpec, typename THost>
 inline void
-clear(DPMatrix_<TValue, TMatrixSpec> & dpMatrix)
+clear(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix)
 {
     clear(_dataLengths(dpMatrix));
     resize(_dataLengths(dpMatrix), 2, 0);
@@ -492,9 +442,9 @@ clear(DPMatrix_<TValue, TMatrixSpec> & dpMatrix)
 // Function empty()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
+template <typename TValue, typename TMatrixSpec, typename THost>
 inline bool
-empty(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
+empty(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix)
 {
     return empty(host(dpMatrix));
 }
@@ -504,9 +454,9 @@ empty(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix)
 // ----------------------------------------------------------------------------
 
 // Sets the new length of a given dimension.
-template <typename TValue, typename TMatrixSpec, typename TSize>
+template <typename TValue, typename TMatrixSpec, typename THost, typename TSize>
 inline void
-setLength(DPMatrix_<TValue, TMatrixSpec> & dpMatrix,
+setLength(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix,
           unsigned int dimension,
           TSize const & newLength)
 {
@@ -518,11 +468,11 @@ setLength(DPMatrix_<TValue, TMatrixSpec> & dpMatrix,
 // Function updateFactors()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Size<DPMatrix_<TValue, TMatrixSpec> >::Type
-updateFactors(DPMatrix_<TValue, TMatrixSpec> & dpMatrix)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Size<DPMatrix_<TValue, TMatrixSpec, THost> >::Type
+updateFactors(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix)
 {
-    typedef typename Size<DPMatrix_<TValue, TMatrixSpec> >::Type TSize;
+    typedef typename Size<DPMatrix_<TValue, TMatrixSpec, THost> >::Type TSize;
 
     TSize factor_ = _dataFactors(dpMatrix)[0] * length(dpMatrix, 0);
     for (unsigned int i = 1; (factor_ > 0) && (i < dimension(value(dpMatrix.data_host))); ++i)
@@ -538,26 +488,26 @@ updateFactors(DPMatrix_<TValue, TMatrixSpec> & dpMatrix)
 // ----------------------------------------------------------------------------
 
 // Resizes the matrix. Note, the lengths of the dimensions have to be set before.
-template <typename TValue, typename TMatrixSpec>
+template <typename TValue, typename TMatrixSpec, typename THost>
 inline void
-resize(DPMatrix_<TValue, TMatrixSpec> & dpMatrix)
+resize(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix)
 {
-    typedef typename Size<DPMatrix_<TValue, TMatrixSpec> >::Type TSize;
+    typedef typename Size<DPMatrix_<TValue, TMatrixSpec, THost> >::Type TSize;
 
     TSize reqSize = updateFactors(dpMatrix);
-    if (reqSize >= length(dpMatrix))
+    if (reqSize > length(dpMatrix))
         resize(host(dpMatrix), reqSize, Exact());
 }
 
-template <typename TValue, typename TMatrixSpec>
+template <typename TValue, typename TMatrixSpec, typename THost>
 inline void
-resize(DPMatrix_<TValue, TMatrixSpec> & dpMatrix,
+resize(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix,
        TValue const & fillValue)
 {
-    typedef typename Size<DPMatrix_<TValue, TMatrixSpec> >::Type TSize;
+    typedef typename Size<DPMatrix_<TValue, TMatrixSpec, THost> >::Type TSize;
 
     TSize reqSize = updateFactors(dpMatrix);
-    if (reqSize >= length(dpMatrix))
+    if (reqSize > length(dpMatrix))
         resize(host(dpMatrix), reqSize, fillValue, Exact());
 }
 
@@ -565,30 +515,30 @@ resize(DPMatrix_<TValue, TMatrixSpec> & dpMatrix,
 // Function begin()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Iterator<DPMatrix_<TValue, TMatrixSpec>, Standard const>::Type
-begin(DPMatrix_<TValue, TMatrixSpec> & dpMatrix, Standard const)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Iterator<DPMatrix_<TValue, TMatrixSpec, THost>, Standard>::Type
+begin(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix, Standard)
 {
     return begin(host(dpMatrix));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Iterator<DPMatrix_<TValue, TMatrixSpec> const, Standard const>::Type
-begin(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix, Standard const)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Iterator<DPMatrix_<TValue, TMatrixSpec, THost> const, Standard>::Type
+begin(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix, Standard)
 {
     return begin(host(dpMatrix));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Iterator<DPMatrix_<TValue, TMatrixSpec>, Rooted const>::Type
-begin(DPMatrix_<TValue, TMatrixSpec> & dpMatrix, Rooted const)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Iterator<DPMatrix_<TValue, TMatrixSpec, THost>, Rooted>::Type
+begin(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix, Rooted)
 {
     return begin(value(dpMatrix.data_host));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Iterator<DPMatrix_<TValue, TMatrixSpec> const, Rooted const>::Type
-begin(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix, Rooted const)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Iterator<DPMatrix_<TValue, TMatrixSpec, THost> const, Rooted>::Type
+begin(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix, Rooted)
 {
     return begin(value(dpMatrix.data_host));
 }
@@ -597,30 +547,30 @@ begin(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix, Rooted const)
 // Function end()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Iterator<DPMatrix_<TValue, TMatrixSpec>, Standard const>::Type
-end(DPMatrix_<TValue, TMatrixSpec> & dpMatrix, Standard const)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Iterator<DPMatrix_<TValue, TMatrixSpec, THost>, Standard>::Type
+end(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix, Standard)
 {
     return end(host(dpMatrix));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Iterator<DPMatrix_<TValue, TMatrixSpec> const, Standard const>::Type
-end(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix, Standard const)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Iterator<DPMatrix_<TValue, TMatrixSpec, THost> const, Standard>::Type
+end(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix, Standard)
 {
     return end(host(dpMatrix));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Iterator<DPMatrix_<TValue, TMatrixSpec>, Rooted const>::Type
-end(DPMatrix_<TValue, TMatrixSpec> & dpMatrix, Rooted const)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Iterator<DPMatrix_<TValue, TMatrixSpec, THost>, Rooted>::Type
+end(DPMatrix_<TValue, TMatrixSpec, THost> & dpMatrix, Rooted)
 {
     return end(value(dpMatrix.data_host));
 }
 
-template <typename TValue, typename TMatrixSpec>
-inline typename Iterator<DPMatrix_<TValue, TMatrixSpec> const, Rooted const>::Type
-end(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix, Rooted const)
+template <typename TValue, typename TMatrixSpec, typename THost>
+inline typename Iterator<DPMatrix_<TValue, TMatrixSpec, THost>, Rooted>::Type
+end(DPMatrix_<TValue, TMatrixSpec, THost> const & dpMatrix, Rooted)
 {
     return end(value(dpMatrix.data_host));
 }
@@ -630,15 +580,31 @@ end(DPMatrix_<TValue, TMatrixSpec> const & dpMatrix, Rooted const)
 // ----------------------------------------------------------------------------
 
 // Returns the coordinate of a host positio in a given dimension.
-template <typename TValue, typename TPosition>
-inline typename Position<DPMatrix_<TValue, FullDPMatrix> >::Type
-coordinate(DPMatrix_<TValue, FullDPMatrix> const & dpMatrix,
+template <typename TValue, typename THost, typename TPosition>
+inline typename Position<DPMatrix_<TValue, FullDPMatrix, THost> >::Type
+coordinate(DPMatrix_<TValue, FullDPMatrix, THost> const & dpMatrix,
            TPosition hostPos,
            typename DPMatrixDimension_::TValue dimension)
 {
     return coordinate(value(dpMatrix.data_host), hostPos, dimension);
 }
 
+// ----------------------------------------------------------------------------
+// Function toGlobalPosition()
+// ----------------------------------------------------------------------------
+
+// Returns the current position of the navigator within the matrix.
+template <typename TValue, typename THost,
+          typename TPosH,
+          typename TPosV>
+inline typename Position<DPMatrix_<TValue, FullDPMatrix, THost> >::Type
+toGlobalPosition(DPMatrix_<TValue, FullDPMatrix, THost> const & dpMatrix,
+                 TPosH const horizontalCoordinate,
+                 TPosV const verticalCoordinate)
+{
+    return horizontalCoordinate * length(dpMatrix, DPMatrixDimension_::VERTICAL) + verticalCoordinate;
+}
+
 } // namespace seqan
 
 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_MATRIX_H_
diff --git a/include/seqan/align/dp_matrix_navigator.h b/include/seqan/align/dp_matrix_navigator.h
index 44d038b..6e0b0c3 100644
--- a/include/seqan/align/dp_matrix_navigator.h
+++ b/include/seqan/align/dp_matrix_navigator.h
@@ -83,6 +83,14 @@ struct NavigateColumnWise_;
 typedef Tag<NavigateColumnWise_> NavigateColumnWise;
 
 // ----------------------------------------------------------------------------
+// Tag NavigateColumnWiseBanded
+// ----------------------------------------------------------------------------
+
+// Facilitates banded column wise navigation through the dp-matrix.
+struct NavigateColumnWiseBanded_;
+typedef Tag<NavigateColumnWiseBanded_> NavigateColumnWiseBanded;
+
+// ----------------------------------------------------------------------------
 // Class DPMatrixNavigator_
 // ----------------------------------------------------------------------------
 
@@ -94,6 +102,24 @@ class DPMatrixNavigator_;
 // ============================================================================
 
 // ----------------------------------------------------------------------------
+// Metafunction MatrixType
+// ----------------------------------------------------------------------------
+
+template <typename TNavigator>
+struct MatrixType;
+
+template <typename TDPMatrix, typename TDPMatrixType, typename TNavigationSpec>
+struct MatrixType<DPMatrixNavigator_<TDPMatrix, TDPMatrixType, TNavigationSpec> >
+{
+    using Type = TDPMatrixType;
+};
+
+template <typename TDPMatrix, typename TDPMatrixType, typename TNavigationSpec>
+struct MatrixType<DPMatrixNavigator_<TDPMatrix, TDPMatrixType, TNavigationSpec> const> :
+    MatrixType<DPMatrixNavigator_<TDPMatrix, TDPMatrixType, TNavigationSpec> >
+{};
+
+// ----------------------------------------------------------------------------
 // Metafunction Value
 // ----------------------------------------------------------------------------
 
@@ -141,6 +167,16 @@ struct Container<DPMatrixNavigator_<TDPMatrix, TDPMatrixType, TNavigationSpec> c
     typedef TDPMatrix const Type;
 };
 
+// ----------------------------------------------------------------------------
+// Metafunction Position
+// ----------------------------------------------------------------------------
+
+template <typename TDPMatrix, typename TDPMatrixType, typename TNavigationSpec>
+struct Position<DPMatrixNavigator_<TDPMatrix, TDPMatrixType, TNavigationSpec> >
+{
+    typedef typename Position<TDPMatrix>::Type Type;
+};
+
 // ============================================================================
 // Functions
 // ============================================================================
diff --git a/include/seqan/align/dp_matrix_navigator_score_matrix.h b/include/seqan/align/dp_matrix_navigator_score_matrix.h
index 56622fe..0ff4e67 100644
--- a/include/seqan/align/dp_matrix_navigator_score_matrix.h
+++ b/include/seqan/align/dp_matrix_navigator_score_matrix.h
@@ -56,21 +56,66 @@ namespace seqan {
 // The navigator for the score matrix.
 //
 // This navigator runs on a FullDPMatrix while it navigates column wise.
-template <typename TValue>
-class DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise>
+
+template <typename TValue, typename THost, typename TNavigationSpec>
+class DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>, DPScoreMatrix, TNavigationSpec>
 {
 public:
-    typedef  DPMatrix_<TValue, FullDPMatrix> TDPMatrix_;
+    typedef  DPMatrix_<TValue, FullDPMatrix, THost> TDPMatrix_;
     typedef typename Pointer_<TDPMatrix_>::Type TDPMatrixPointer_;
     typedef typename Iterator<TDPMatrix_, Standard>::Type TDPMatrixIterator;
 
-    TDPMatrixPointer_ _ptrDataContainer     = nullptr;  // Pointer to the matrix this navigator is working on.
-    int _laneLeap                           = 0;  // Stores the jump to the next column
-    TDPMatrixIterator _activeColIterator    = TDPMatrixIterator();  // The active column iterator.
-    TDPMatrixIterator _prevColIterator      = TDPMatrixIterator();  // The previous column iterator.
-    TValue _prevCellDiagonal                = TValue();  // The previous diagonal cell
-    TValue _prevCellHorizontal              = TValue();  // The previous Horizontal cell
-    TValue _prevCellVertical                = TValue();  // The previous Vertical cell
+    template <typename TBandSpec,
+              std::enable_if_t<std::is_same<TBandSpec, BandOff>::value, int> = 0>
+    DPMatrixNavigator_(TDPMatrix_ & matrix,
+                       DPBandConfig<TBandSpec> const & /*band*/)
+    {
+        _ptrDataContainer = &matrix;
+        _prevColIteratorOffset = _dataFactors(matrix)[DPMatrixDimension_::HORIZONTAL];
+        _activeColIterator = begin(matrix, Standard());
+        _prevColIterator = _activeColIterator - _prevColIteratorOffset;
+        _laneLeap = 1;
+        *_activeColIterator = TValue();
+    }
+
+    template <typename TBandSpec,
+              std::enable_if_t<!std::is_same<TBandSpec, BandOff>::value, int> = 0>
+    DPMatrixNavigator_(TDPMatrix_ & matrix,
+                       DPBandConfig<TBandSpec> const & band)
+    {
+        using TMatrixSize = typename Size<TDPMatrix_>::Type;
+        using TSignedSize = std::make_signed_t<TMatrixSize>;
+
+        _ptrDataContainer = &matrix;
+        _prevColIteratorOffset = _dataFactors(matrix)[DPMatrixDimension_::HORIZONTAL];
+        // Band begins within the first row.
+        if (lowerDiagonal(band) >= 0)
+        {
+            _laneLeap = _min(length(matrix, DPMatrixDimension_::VERTICAL), bandSize(band));
+            _activeColIterator = begin(matrix, Standard()) + _dataLengths(matrix)[DPMatrixDimension_::VERTICAL] - 1;
+        }
+        else if (upperDiagonal(band) <= 0)  // Band begins within the first column.
+        {
+            _laneLeap = 1;
+            _activeColIterator = begin(matrix, Standard());
+        }
+        else  // Band intersects with the point of origin.
+        {
+            TMatrixSize lengthVertical = length(matrix, DPMatrixDimension_::VERTICAL);
+            int lastPos = _max(-static_cast<TSignedSize>(lengthVertical - 1), lowerDiagonal(band));
+            _laneLeap = lengthVertical + lastPos;
+            _activeColIterator = begin(matrix, Standard()) + _laneLeap - 1;
+        }
+        // Set previous iterator to same position, one column left.
+        _prevColIterator = _activeColIterator - _prevColIteratorOffset;
+        *_activeColIterator = TValue();
+    }
+
+    TDPMatrixPointer_ _ptrDataContainer{nullptr};   // Pointer to the matrix this navigator is working on.
+    int               _laneLeap{0};                 // Stores the jump to the next column
+    size_t            _prevColIteratorOffset{0};    // Offset to reset the previous column iterator when going to the next cell.
+    TDPMatrixIterator _activeColIterator{};         // The active column iterator.
+    TDPMatrixIterator _prevColIterator{};           // The previous column iterator.
 };
 
 // ============================================================================
@@ -82,324 +127,286 @@ public:
 // ============================================================================
 
 // ----------------------------------------------------------------------------
-// Function _init()
+// Function _goNextCell                                     [banded, FirstCell]
 // ----------------------------------------------------------------------------
 
-// Initializes the navigator for an unbanded alignment.
-template <typename TValue>
+// Needed to avoid ambigious overload.
+template <typename TValue, typename TDPMatrixSpec, typename THost>
 inline void
-_init(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & navigator,
-      DPMatrix_<TValue, FullDPMatrix> & dpMatrix,
-      DPBandConfig<BandOff> const &)
-{
-    navigator._ptrDataContainer = &dpMatrix;
-    navigator._activeColIterator = begin(dpMatrix, Standard());
-    navigator._prevColIterator = navigator._activeColIterator - _dataFactors(dpMatrix)[DPMatrixDimension_::HORIZONTAL];
-    navigator._laneLeap = 1;
-    *navigator._activeColIterator =  TValue();
-}
-
-// Initializes the navigator for a banded alignment.
-template <typename TValue>
-inline void
-_init(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & navigator,
-      DPMatrix_<TValue, FullDPMatrix> & dpMatrix,
-      DPBandConfig<BandOn> const & band)
-{
-    typedef typename Size<DPMatrix_<TValue, FullDPMatrix> >::Type TMatrixSize;
-    typedef typename MakeSigned<TMatrixSize>::Type TSignedSize;
-    navigator._ptrDataContainer = &dpMatrix;
-
-
-    // Band begins within the first row.
-    if (lowerDiagonal(band) >= 0)
-    {
-        navigator._laneLeap = _min(length(dpMatrix, DPMatrixDimension_::VERTICAL), bandSize(band));
-        navigator._activeColIterator = begin(dpMatrix, Standard()) + _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL] - 1;
-    }
-    else if (upperDiagonal(band) <= 0)  // Band begins within the first column.
-    {
-        navigator._laneLeap = 1;
-        navigator._activeColIterator = begin(dpMatrix, Standard());
-    }
-    else  // Band intersects with the point of origin.
-    {
-        TMatrixSize lengthVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL);
-        int lastPos = _max(-static_cast<TSignedSize>(lengthVertical - 1), lowerDiagonal(band));
-        navigator._laneLeap = lengthVertical + lastPos;
-        navigator._activeColIterator = begin(dpMatrix, Standard()) + navigator._laneLeap - 1;
-    }
-    // Set previous iterator to same position, one column left.
-    navigator._prevColIterator = navigator._activeColIterator - _dataFactors(dpMatrix)[DPMatrixDimension_::HORIZONTAL];
-    *navigator._activeColIterator =  TValue();
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                          [DPInitialColumn, FirstCell]
-// ----------------------------------------------------------------------------
-
-// In the initial column we don't need to do anything because, the navigagtor is already initialized.
-template <typename TValue>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & /*dpNavigator*/,
             MetaColumnDescriptor<DPInitialColumn, PartialColumnTop> const &,
             FirstCell const &)
 {
     // no-op
 }
 
-template <typename TValue>
+// Needed to avoid ambigious overload.
+template <typename TValue, typename TDPMatrixSpec, typename THost>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & /*dpNavigator*/,
             MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
             FirstCell const &)
 {
     // no-op
 }
 
-template <typename TValue, typename TColumnLocation>
+// specialized for initialization column and all other column locations.
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & /*dpNavigator*/,
             MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
             FirstCell const &)
 {
     // no-op
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                         [PartialColumnTop, FirstCell]
-// ----------------------------------------------------------------------------
-
-// We are in the banded case, where the band crosses the first row.
-// The left cell of the active cell is not valid, beacause we only can come from horizontal direction.
-// The lower left cell of the active cell is the horizontal direction.
-template <typename TValue, typename TColumnType>
+//  specialized for all other column types located at the top.
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, PartialColumnTop> const &,
             FirstCell const &)
 {
     --dpNavigator._laneLeap;
     dpNavigator._activeColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
+    dpNavigator._prevColIterator = dpNavigator._activeColIterator - dpNavigator._prevColIteratorOffset + 1;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                               [FullColumn, FirstCell]
-// ----------------------------------------------------------------------------
-
-// We are in the unbanded case or in the middle phase of the wide band.
-// The left cell of the active cell represents horizontal direction.
-template <typename TValue, typename TColumnType>
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, FullColumn> const &,
             FirstCell const &)
 {
     dpNavigator._activeColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevCellHorizontal = value(dpNavigator._prevColIterator);
+    dpNavigator._prevColIterator = dpNavigator._activeColIterator - dpNavigator._prevColIteratorOffset;
+}
+
+// version for all other column types and locations.
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnType, typename TColumnLocation>
+inline void
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
+            MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
+            FirstCell const &)
+{
+    dpNavigator._activeColIterator += dpNavigator._laneLeap;
+    dpNavigator._prevColIterator = dpNavigator._activeColIterator - dpNavigator._prevColIteratorOffset + 1;
 }
 
 // ----------------------------------------------------------------------------
-// Function _goNextCell() [PartialColumnMiddle, PartialColumnBottom, FirstCell]
+// Function _goNextCell                                   [unbanded, FirstCell]
 // ----------------------------------------------------------------------------
 
-// We are in the banded case.
-// The left cell of the active cell represents diagonal direction. The lower left diagonal represents the horizontal direction.
+// specialized for initalization column.
+template <typename TValue, typename THost>
+inline void
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/,
+            MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
+            FirstCell const &)
+{
+    // no-op
+}
 
-template <typename TValue, typename TColumnType, typename TColumnLocation>
+// all other column types.
+template <typename TValue, typename THost,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<TColumnType, FullColumn> const &,
             FirstCell const &)
 {
+    // Set to begin of column.
     dpNavigator._activeColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevCellDiagonal = value(dpNavigator._prevColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
+    dpNavigator._prevColIterator = dpNavigator._activeColIterator - dpNavigator._prevColIteratorOffset;
+
 }
 
 // ----------------------------------------------------------------------------
-// Function _goNextCell                            [DPInitialColumn, InnerCell]
+// Function _goNextCell                                     [banded, InnerCell]
 // ----------------------------------------------------------------------------
 
-// If we are in the initial column, we only need to represent the vertical direction.
-// But we still have to update the previous column iterator.
-template <typename TValue, typename TColumnLocation>
+// specilized for the initialization column and all column locations.
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
             InnerCell const &)
 {
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
     ++dpNavigator._activeColIterator;
-    ++dpNavigator._prevColIterator;  // Do we have to increase the prevColIterator....
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell                                  [AnyColumn, InnerCell]
-// ----------------------------------------------------------------------------
-
-// For any other column type and location we can use the same navigation procedure.
-template <typename TValue, typename TColumnType, typename TColumnLocation>
+// specialized for the standard band processing.
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnType, typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
             InnerCell const &)
 {
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
     ++dpNavigator._activeColIterator;
+    ++dpNavigator._prevColIterator;
 }
 
 // ----------------------------------------------------------------------------
-// Function _goNextCell                             [DPInitialColumn, LastCell]
+// Function _goNextCell                                   [unbanded, InnerCell]
 // ----------------------------------------------------------------------------
 
-// If we are in the initial column we only need to represent the vertical direction.
-// But we still have to update the previous column iterator.
-template <typename TValue, typename TColumnLocation>
+// specialized for the initialization column.
+template <typename TValue, typename THost>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
-            LastCell const &)
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
+            InnerCell const &)
 {
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
     ++dpNavigator._activeColIterator;
-    ++dpNavigator._prevColIterator;
 }
 
-// We need this function to avoid ambiguous function calls.
-template <typename TValue>
+// version for the all other column types.
+template <typename TValue, typename THost,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom> const &,
-            LastCell const &)
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<TColumnType, FullColumn> const &,
+            InnerCell const &)
 {
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
     ++dpNavigator._activeColIterator;
     ++dpNavigator._prevColIterator;
 }
 
-// We need this function to avoid ambiguous function calls.
-template <typename TValue>
+// ----------------------------------------------------------------------------
+// Function _goNextCell                                      [banded, LastCell]
+// ----------------------------------------------------------------------------
+
+// specilaized for initialization column and bottom column.
+template <typename TValue, typename TDPMatrixSpec, typename THost>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
+            MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom> const &,
             LastCell const &)
 {
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
     ++dpNavigator._activeColIterator;
-    ++dpNavigator._prevColIterator;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell                                  [FullColumn, LastCell]
-// ----------------------------------------------------------------------------
-
-// If we are in a full column the values correspond to standard dp directions.
-template <typename TValue, typename TColumnType>
+// specilaized for initialization column and all other column locations.
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<TColumnType, FullColumn> const &,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
+            MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
             LastCell const &)
 {
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
     ++dpNavigator._activeColIterator;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell                         [PartialColumnBottom, LastCell]
-// ----------------------------------------------------------------------------
-
-// If we are in banded case and are the band crosses the last row, we have to update
-// the additional leap for the current track.
-template <typename TValue, typename TColumnType>
+// specialized for all column types and bottom column.
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, PartialColumnBottom> const &,
             LastCell const &)
 {
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
     ++dpNavigator._activeColIterator;
+    ++dpNavigator._prevColIterator;
     ++dpNavigator._laneLeap;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell      [PartialColumnTop & PartialColumnBottom, LastCell]
-// ----------------------------------------------------------------------------
-
-// If we are in the banded case the left cell of the active represents the diagonal direction.
-template <typename TValue, typename TColumnType, typename TColumnLocation>
+// generic case for all other column types and column locations.
+template <typename TValue, typename TDPMatrixSpec, typename THost,
+          typename TColumnType, typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, TDPMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
             LastCell const &)
 {
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
     ++dpNavigator._activeColIterator;
+    ++dpNavigator._prevColIterator;
 }
 
 // ----------------------------------------------------------------------------
-// Function previousCellDiagonal()
+// Function _goNextCell                                    [unbanded, LastCell]
 // ----------------------------------------------------------------------------
 
-template <typename TDPMatrix, typename TNavigationSpec>
-inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> >::Type
-previousCellDiagonal(DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> & dpNavigator)
+// specilaized for initialization column.
+template <typename TValue, typename THost>
+inline void
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
+            LastCell const &)
 {
-    return dpNavigator._prevCellDiagonal;
+    ++dpNavigator._activeColIterator;
 }
 
-template <typename TDPMatrix, typename TNavigationSpec>
-inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> const>::Type
-previousCellDiagonal(DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> const & dpNavigator)
+// version for all other column types.
+template <typename TValue, typename THost,
+          typename TColumnType>
+inline void
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<TColumnType, FullColumn> const &,
+            LastCell const &)
 {
-    return dpNavigator._prevCellDiagonal;
+    ++dpNavigator._activeColIterator; // go to next cell.
+    ++dpNavigator._prevColIterator; // go to next cell.
 }
 
 // ----------------------------------------------------------------------------
-// Function previousCellHorizontal()
+// Function _preInitCacheDiagonal()
 // ----------------------------------------------------------------------------
 
-template <typename TDPMatrix, typename TNavigationSpec>
-inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> >::Type
-previousCellHorizontal(DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> & dpNavigator)
+template <typename TDPCell,
+          typename TValue, typename TMatrixSpec, typename THost,
+          typename TColumnType>
+inline void
+_preInitCacheDiagonal(TDPCell & cacheDiagonal,
+                      DPMatrixNavigator_<DPMatrix_<TValue, TMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> const & dpNavigator,
+                      MetaColumnDescriptor<TColumnType, PartialColumnMiddle> const & /*tag*/)
 {
-    return dpNavigator._prevCellHorizontal;
+    _scoreOfCell(cacheDiagonal) = _scoreOfCell(*(dpNavigator._prevColIterator - 1));
 }
 
-template <typename TDPMatrix, typename TNavigationSpec>
-inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> const>::Type
-previousCellHorizontal(DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> const & dpNavigator)
+template <typename TDPCell,
+          typename TValue, typename TMatrixSpec, typename THost,
+          typename TColumnType>
+inline void
+_preInitCacheDiagonal(TDPCell & cacheDiagonal,
+                      DPMatrixNavigator_<DPMatrix_<TValue, TMatrixSpec, THost>, DPScoreMatrix, NavigateColumnWiseBanded> const & dpNavigator,
+                      MetaColumnDescriptor<TColumnType, PartialColumnBottom> const & /*tag*/)
 {
-    return dpNavigator._prevCellHorizontal;
+    _scoreOfCell(cacheDiagonal) = _scoreOfCell(*(dpNavigator._prevColIterator - 1));
+}
+
+template <typename TDPCell,
+          typename TValue, typename TMatrixSpec, typename THost, typename TNavigationSpec,
+          typename TColumnType, typename TColumnLocation>
+inline void
+_preInitCacheDiagonal(TDPCell & /*cacheDiagonal*/,
+                      DPMatrixNavigator_<DPMatrix_<TValue, TMatrixSpec, THost>, DPScoreMatrix, TNavigationSpec> const & /*dpNavigator*/,
+                      MetaColumnDescriptor<TColumnType, TColumnLocation> const & /*tag*/)
+{
+    // no-op
 }
 
 // ----------------------------------------------------------------------------
-// Function previousCellVertical()
+// Function previousCellHorizontal()
 // ----------------------------------------------------------------------------
 
 template <typename TDPMatrix, typename TNavigationSpec>
 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> >::Type
-previousCellVertical(DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> & dpNavigator)
+previousCellHorizontal(DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> & dpNavigator)
 {
-    return dpNavigator._prevCellVertical;
+    return *dpNavigator._prevColIterator;
 }
 
 template <typename TDPMatrix, typename TNavigationSpec>
 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> const>::Type
-previousCellVertical(DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> const & dpNavigator)
+previousCellHorizontal(DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, TNavigationSpec> const & dpNavigator)
 {
-    return dpNavigator._prevCellVertical;
+    return *dpNavigator._prevColIterator;
 }
 
 }  // namespace seqan
diff --git a/include/seqan/align/dp_matrix_navigator_score_matrix_sparse.h b/include/seqan/align/dp_matrix_navigator_score_matrix_sparse.h
index 4202d56..a68d9a1 100644
--- a/include/seqan/align/dp_matrix_navigator_score_matrix_sparse.h
+++ b/include/seqan/align/dp_matrix_navigator_score_matrix_sparse.h
@@ -1,3 +1,4 @@
+
 // ==========================================================================
 //                 SeqAn - The Library for Sequence Analysis
 // ==========================================================================
@@ -54,21 +55,60 @@ namespace seqan {
 // ----------------------------------------------------------------------------
 
 // Specialization of the score matrix navigator for a sparse dp matrix.
-template <typename TValue>
-class DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise>
+template <typename TValue, typename THost, typename TNavigationSpec>
+class DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>, DPScoreMatrix, TNavigationSpec>
 {
 public:
-    typedef  DPMatrix_<TValue, SparseDPMatrix> TDPMatrix_;
+    typedef  DPMatrix_<TValue, SparseDPMatrix, THost> TDPMatrix_;
     typedef typename Pointer_<TDPMatrix_>::Type TDPMatrixPointer_;
     typedef typename Iterator<TDPMatrix_, Standard>::Type TDPMatrixIterator;
 
-    TDPMatrixPointer_ _ptrDataContainer     = nullptr;  // Pointer to the underlying matrix to navigate on.
-    int _laneLeap                           = 0;  // The distance to leap when going to the next column.
-    TDPMatrixIterator _activeColIterator    = TDPMatrixIterator();  // The iterator over the active column.
-    TDPMatrixIterator _prevColIterator      = TDPMatrixIterator();  // The iterator over the previous column.
-    TValue _prevCellDiagonal                = TValue();  // The previous value in diagonal direction.
-    TValue _prevCellHorizontal              = TValue();  // The previous value in horizontal direction.
-    TValue _prevCellVertical                = TValue();  // The previous value in vertical direction.
+    template <typename TBandSpec,
+              std::enable_if_t<std::is_same<TBandSpec, BandOff>::value, int> = 0>
+    DPMatrixNavigator_(TDPMatrix_ & matrix,
+                       DPBandConfig<TBandSpec> const & /*band*/)
+    {
+        _ptrDataContainer = &matrix;
+        _activeColIterator = begin(matrix, Standard());
+        _prevColIterator = _activeColIterator;
+        _laneLeap = 1 - _dataLengths(matrix)[DPMatrixDimension_::VERTICAL];
+        *_activeColIterator = TValue();
+    }
+
+    template <typename TBandSpec,
+              std::enable_if_t<!std::is_same<TBandSpec, BandOff>::value, int> = 0>
+    DPMatrixNavigator_(TDPMatrix_ & matrix,
+                       DPBandConfig<TBandSpec> const & band)
+    {
+        typedef typename Size<TDPMatrix_>::Type TSize;
+        typedef std::make_signed_t<TSize> TSignedSize;
+        _ptrDataContainer = &matrix;
+
+        // Band begins within the first row.
+        if (lowerDiagonal(band) >= 0)
+        {
+            _laneLeap = 0;
+            _activeColIterator = begin(matrix, Standard()) + length(matrix, DPMatrixDimension_::VERTICAL) - 1;
+        }
+        else if (upperDiagonal(band) <= 0) // Band begins within the first column
+        {
+            _laneLeap = 1 - _dataLengths(matrix)[DPMatrixDimension_::VERTICAL];
+            _activeColIterator = begin(matrix, Standard());
+        }
+        else  // Band intersects with the point of origin.
+        {
+            _laneLeap = _max(lowerDiagonal(band), 1 - static_cast<TSignedSize>(length(matrix, DPMatrixDimension_::VERTICAL)));
+            _activeColIterator = begin(matrix, Standard()) + length(matrix, DPMatrixDimension_::VERTICAL) + _laneLeap - 1;
+        }
+        _prevColIterator = _activeColIterator;
+        *_activeColIterator = TValue();
+    }
+
+    TDPMatrixPointer_ _ptrDataContainer{nullptr};   // Pointer to the underlying matrix to navigate on.
+    int               _laneLeap{0};                 // The distance to leap when going to the next column.
+    size_t            _prevColIteratorOffset{0};    // Offset to reset the previous column iterator when going to the next cell.
+    TDPMatrixIterator _activeColIterator{};         // The iterator over the active column.
+    TDPMatrixIterator _prevColIterator{};           // The iterator over the previous column. Only needed in the banded case.
 };
 
 // ============================================================================
@@ -80,288 +120,133 @@ public:
 // ============================================================================
 
 // ----------------------------------------------------------------------------
-// Function _init()
-// ----------------------------------------------------------------------------
-
-
-// Initializes the navigator for unbanded alignments
-template <typename TValue>
-inline void
-_init(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & navigator,
-      DPMatrix_<TValue, SparseDPMatrix> & dpMatrix,
-      DPBandConfig<BandOff> const &)
-{
-    navigator._ptrDataContainer = &dpMatrix;
-    navigator._activeColIterator = begin(dpMatrix, Standard());
-    navigator._prevColIterator = navigator._activeColIterator;
-    navigator._laneLeap = 1 - _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL];
-    *navigator._activeColIterator = TValue();
-}
-
-// Initializes the navigator for banded alignments
-template <typename TValue>
-inline void
-_init(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & navigator,
-      DPMatrix_<TValue, SparseDPMatrix> & dpMatrix,
-      DPBandConfig<BandOn> const & band)
-{
-    typedef DPMatrix_<TValue, SparseDPMatrix> TSparseDPMatrix;
-    typedef typename Size<TSparseDPMatrix>::Type TSize;
-    typedef typename MakeSigned<TSize>::Type TSignedSize;
-    navigator._ptrDataContainer = &dpMatrix;
-
-    // Band begins within the first row.
-    if (lowerDiagonal(band) >= 0)
-    {
-        navigator._laneLeap = 0;
-        navigator._activeColIterator = begin(dpMatrix, Standard()) + length(dpMatrix, DPMatrixDimension_::VERTICAL) - 1;
-    }
-    else if (upperDiagonal(band) <= 0) // Band begins within the first column
-    {
-        navigator._laneLeap = 1 - _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL];
-        navigator._activeColIterator = begin(dpMatrix, Standard());
-    }
-    else  // Band intersects with the point of origin.
-    {
-        navigator._laneLeap = _max(lowerDiagonal(band), 1 - static_cast<TSignedSize>(length(dpMatrix, DPMatrixDimension_::VERTICAL)));
-        navigator._activeColIterator = begin(dpMatrix, Standard()) + length(dpMatrix, DPMatrixDimension_::VERTICAL) + navigator._laneLeap - 1;
-    }
-    navigator._prevColIterator = navigator._activeColIterator;
-    *navigator._activeColIterator = TValue();
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell()        [DPInitialColumn, PartialColumnTop, FirstCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/,
-            MetaColumnDescriptor<DPInitialColumn, PartialColumnTop> const &,
-            FirstCell const &)
-{
-    // no-op
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell()              [DPInitialColumn, FullColumn, FirstCell]
+// Function _goNextCell                                   [unbanded, FirstCell]
 // ----------------------------------------------------------------------------
 
-template <typename TValue>
+// specialized for initalization column.
+template <typename TValue, typename THost>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/,
             MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
             FirstCell const &)
 {
     // no-op
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                          [DPInitialColumn, FirstCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TColumnLocation>
+// all other column types.
+template <typename TValue, typename THost,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & /*dpNavigator*/,
-            MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
-            FirstCell const &)
-{
-    // no-op
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                         [PartialColumnTop, FirstCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TColumnType>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<TColumnType, PartialColumnTop> const &,
-            FirstCell const &)
-{
-    --dpNavigator._laneLeap;
-    dpNavigator._activeColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevColIterator = dpNavigator._activeColIterator;
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                               [FullColumn, FirstCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TColumnType>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
             MetaColumnDescriptor<TColumnType, FullColumn> const &,
             FirstCell const &)
 {
+    // Set to begin of column.
     dpNavigator._activeColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevCellHorizontal = value(dpNavigator._activeColIterator);
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                                           [FirstCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TColumnType, typename TColumnLocation>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
-            FirstCell const &)
-{
-    dpNavigator._activeColIterator += dpNavigator._laneLeap;
-    dpNavigator._prevColIterator = dpNavigator._activeColIterator;
-    dpNavigator._prevCellDiagonal = value(dpNavigator._prevColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
 }
 
 // ----------------------------------------------------------------------------
-// Function _goNextCell                            [DPInitialColumn, InnerCell]
+// Function _goNextCell                                   [unbanded, InnerCell]
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TColumnLocation>
+// specialized for the initialization column.
+template <typename TValue, typename THost>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
-            InnerCell const &)
-{
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    ++dpNavigator._activeColIterator;
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell                [DPInitialColumn, FullColumn, InnerCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
             MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
             InnerCell const &)
 {
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    ++dpNavigator._activeColIterator;
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell                                             [InnerCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TColumnType, typename TColumnLocation>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
-            InnerCell const &)
-{
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
     ++dpNavigator._activeColIterator;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell                                 [FullColumn, InnerCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TColumnType>
+// version for the all other column types.
+template <typename TValue, typename THost,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
             MetaColumnDescriptor<TColumnType, FullColumn> const &,
             InnerCell const &)
 {
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._activeColIterator);
+    ++dpNavigator._activeColIterator;
 }
 
 // ----------------------------------------------------------------------------
-// Function _goNextCell                             [DPInitialColumn, LastCell]
+// Function _goNextCell                                    [unbanded, LastCell]
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TColumnLocation>
+// specilaized for initialization column.
+template <typename TValue, typename THost>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
             LastCell const &)
 {
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
     ++dpNavigator._activeColIterator;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell        [DPInitialColumn, PartialColumnBottom, LastCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue>
+// version for all other column types.
+template <typename TValue, typename THost,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom> const &,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<TColumnType, FullColumn> const &,
             LastCell const &)
 {
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    ++dpNavigator._activeColIterator;
+    ++dpNavigator._activeColIterator; // go to next cell.
 }
 
 // ----------------------------------------------------------------------------
-// Function _goNextCell                 [DPInitialColumn, FullColumn, LastCell]
+// Function previousCellHorizontal()
 // ----------------------------------------------------------------------------
 
-template <typename TValue>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
-            LastCell const &)
+// unbanded.
+template <typename TValue, typename THost>
+inline typename Reference<DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>,
+                                             DPScoreMatrix,
+                                             NavigateColumnWise>
+                         >::Type
+previousCellHorizontal(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>,
+                                          DPScoreMatrix,
+                                          NavigateColumnWise> & dpNavigator)
 {
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    ++dpNavigator._activeColIterator;
+    return *dpNavigator._activeColIterator;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell                                              [LastCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TColumnType, typename TColumnLocation>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
-            LastCell const &)
+template <typename TValue, typename THost, typename TNavigationSpec>
+inline typename Reference<DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>,
+                                             DPScoreMatrix,
+                                             NavigateColumnWise> const
+                         >::Type
+previousCellHorizontal(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>,
+                                          DPScoreMatrix,
+                                          NavigateColumnWise> const & dpNavigator)
 {
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    ++dpNavigator._activeColIterator;
+    return *dpNavigator._activeColIterator;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell                         [PartialColumnBottom, LastCell]
-// ----------------------------------------------------------------------------
-
-template <typename TValue, typename TColumnType>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<TColumnType, PartialColumnBottom> const &,
-            LastCell const &)
+// banded.
+template <typename TValue, typename THost>
+inline typename Reference<DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>,
+                                             DPScoreMatrix,
+                                             NavigateColumnWiseBanded>
+                         >::Type
+previousCellHorizontal(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>,
+                                          DPScoreMatrix,
+                                          NavigateColumnWiseBanded> & dpNavigator)
 {
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._prevColIterator);
-    ++dpNavigator._activeColIterator;
-    ++dpNavigator._laneLeap;
+    return *dpNavigator._prevColIterator;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell                                  [FullColumn, LastCell]
-// ----------------------------------------------------------------------------
-
-
-template <typename TValue, typename TColumnType>
-inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix>, DPScoreMatrix, NavigateColumnWise> & dpNavigator,
-            MetaColumnDescriptor<TColumnType, FullColumn> const &,
-            LastCell const &)
+template <typename TValue, typename THost>
+inline typename Reference<DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>,
+                                             DPScoreMatrix,
+                                             NavigateColumnWiseBanded> const
+                         >::Type
+previousCellHorizontal(DPMatrixNavigator_<DPMatrix_<TValue, SparseDPMatrix, THost>,
+                                          DPScoreMatrix,
+                                          NavigateColumnWiseBanded> const & dpNavigator)
 {
-    dpNavigator._prevCellDiagonal = dpNavigator._prevCellHorizontal;
-    dpNavigator._prevCellVertical = value(dpNavigator._activeColIterator);
-    dpNavigator._prevCellHorizontal = value(++dpNavigator._activeColIterator);
+    return *(dpNavigator._prevColIterator);
 }
 
 }  // namespace seqan
diff --git a/include/seqan/align/dp_matrix_navigator_trace_matrix.h b/include/seqan/align/dp_matrix_navigator_trace_matrix.h
index af944ee..9b27ea3 100644
--- a/include/seqan/align/dp_matrix_navigator_trace_matrix.h
+++ b/include/seqan/align/dp_matrix_navigator_trace_matrix.h
@@ -64,19 +64,70 @@ namespace seqan {
 // specifies that this is a trace-matrix navigator while the TTraceFlag can either
 // be TracebackOn to enable the navigator or TracebackOff to disable it.
 // The last parameter specifies the kind of navigation.
-template <typename TValue, typename TTraceFlag>
-class DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise>
+template <typename TValue, typename THost, typename TTraceFlag, typename TNavigationSpec>
+class DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>, DPTraceMatrix<TTraceFlag>, TNavigationSpec>
 {
 public:
 
-    typedef  DPMatrix_<TValue, FullDPMatrix> TDPMatrix_;
+    typedef  DPMatrix_<TValue, FullDPMatrix, THost> TDPMatrix_;
     typedef typename Pointer_<TDPMatrix_>::Type TDPMatrixPointer_;
     typedef typename Iterator<TDPMatrix_, Standard>::Type TDPMatrixIterator;
 
-    TDPMatrixPointer_   _ptrDataContainer  = nullptr;  // The pointer to the underlying Matrix.
-    int                 _laneLeap          = 0;  // Keeps track of the jump size from one column to another.
-    unsigned            _simdLane          = 0;  // Used for tracing the correct cell in case of simd vectors.
-    TDPMatrixIterator   _activeColIterator = TDPMatrixIterator();  // The current column iterator.
+    template <typename TBandSpec,
+              std::enable_if_t<std::is_same<TBandSpec, BandOff>::value, int> = 0>
+    DPMatrixNavigator_(TDPMatrix_ & matrix,
+                       DPBandConfig<TBandSpec> const & /*band*/)
+    {
+        if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+            return;  // Leave navigator uninitialized because it is never used.
+
+        _ptrDataContainer = &matrix;
+        _activeColIterator = begin(matrix, Standard());
+        _laneLeap = 1;
+        *_activeColIterator = TValue();
+    }
+
+    template <typename TBandSpec,
+              std::enable_if_t<!std::is_same<TBandSpec, BandOff>::value, int> = 0>
+    DPMatrixNavigator_(TDPMatrix_ & matrix,
+                       DPBandConfig<TBandSpec> const & band)
+    {
+        using TMatrixSize = typename Size<TDPMatrix_>::Type;
+        using TSignedSize = std::make_signed_t<TMatrixSize>;
+
+        if (std::is_same<TTraceFlag, TracebackOff>::value)
+            return;  // Leave navigator as is because it should never be used.
+
+        _ptrDataContainer = &matrix;
+
+        // Band begins within the first row.
+        if (lowerDiagonal(band) >= 0)
+        {
+            // The first cell of the first column starts at the last cell in the matrix of the current column.
+            _laneLeap = _min(length(matrix, DPMatrixDimension_::VERTICAL), bandSize(band));
+            _activeColIterator = begin(matrix, Standard()) + _dataLengths(matrix)[DPMatrixDimension_::VERTICAL] - 1;
+        }
+        else if (upperDiagonal(band) <= 0)  // Band begins within the first column.
+        {
+            // The first cell starts at the beginning of the current column.
+            _laneLeap = 1;
+            _activeColIterator = begin(matrix, Standard());
+        }
+        else  // Band intersects with the point of origin.
+        {
+            // First cell starts at position i, such that i + abs(lowerDiagonal) = length(seqV).
+            TMatrixSize lengthVertical = length(matrix, DPMatrixDimension_::VERTICAL);
+            int lastPos = _max(-static_cast<TSignedSize>(lengthVertical - 1), lowerDiagonal(band));
+            _laneLeap = lengthVertical + lastPos;
+            _activeColIterator = begin(matrix, Standard()) + _laneLeap - 1;
+        }
+        *_activeColIterator = TValue();
+    }
+
+    TDPMatrixPointer_   _ptrDataContainer{nullptr}; // The pointer to the underlying Matrix.
+    int                 _laneLeap{0};               // Keeps track of the jump size from one column to another.
+    unsigned            _simdLane{0};               // Used for tracing the correct cell in case of simd vectors.
+    TDPMatrixIterator   _activeColIterator{};       // The current column iterator.
 };
 
 // ============================================================================
@@ -88,99 +139,43 @@ public:
 // ============================================================================
 
 // ----------------------------------------------------------------------------
-// Function _init()
-// ----------------------------------------------------------------------------
-
-// Initializes the navigator for unbanded alignments.
-template <typename TValue, typename TTraceFlag>
-inline void
-_init(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & navigator,
-      DPMatrix_<TValue, FullDPMatrix> & dpMatrix,
-      DPBandConfig<BandOff> const &)
-{
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
-        return;  // Leave navigator uninitialized because it is never used.
-
-    navigator._ptrDataContainer = &dpMatrix;
-    navigator._activeColIterator = begin(dpMatrix, Standard());
-    navigator._laneLeap = 1;
-    *navigator._activeColIterator = TValue();
-}
-
-// Initializes the navigator for banded alignments.
-// Note, the band size has a maximal width of length of the vertical sequence.
-template <typename TValue, typename TTraceFlag>
-inline void
-_init(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & navigator,
-      DPMatrix_<TValue, FullDPMatrix> & dpMatrix,
-      DPBandConfig<BandOn> const & band)
-{
-    typedef typename Size<DPMatrix_<TValue, FullDPMatrix> >::Type TMatrixSize;
-    typedef typename MakeSigned<TMatrixSize>::Type TSignedSize;
-
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
-        return;  // Leave navigator as is because it should never be used.
-
-    navigator._ptrDataContainer = &dpMatrix;
-
-    // Band begins within the first row.
-    if (lowerDiagonal(band) >= 0)
-    {
-        // The first cell of the first column starts at the last cell in the matrix of the current column.
-        navigator._laneLeap = _min(length(dpMatrix, DPMatrixDimension_::VERTICAL), bandSize(band));
-        navigator._activeColIterator = begin(dpMatrix, Standard()) + _dataLengths(dpMatrix)[DPMatrixDimension_::VERTICAL] - 1;
-    }
-    else if (upperDiagonal(band) <= 0)  // Band begins within the first column.
-    {
-        // The first cell starts at the beginning of the current column.
-        navigator._laneLeap = 1;
-        navigator._activeColIterator = begin(dpMatrix, Standard());
-    }
-    else  // Band intersects with the point of origin.
-    {
-        // First cell starts at position i, such that i + abs(lowerDiagonal) = length(seqV).
-        TMatrixSize lengthVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL);
-        int lastPos = _max(-static_cast<TSignedSize>(lengthVertical - 1), lowerDiagonal(band));
-        navigator._laneLeap = lengthVertical + lastPos;
-        navigator._activeColIterator = begin(dpMatrix, Standard()) + navigator._laneLeap - 1;
-    }
-    *navigator._activeColIterator = TValue();
-}
-
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                          [DPInitialColumn, FirstCell]
+// Function _goNextCell()                                   [banded, FirstCell]
 // ----------------------------------------------------------------------------
 
 // In the initial column we don't need to do anything because, the navigagtor is already initialized.
-template <typename TValue, typename TTraceFlag>
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & /*dpNavigator*/,
-            MetaColumnDescriptor<DPInitialColumn, PartialColumnTop> const &,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWiseBanded> & /*dpNavigator*/,
+            MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
             FirstCell const &)
 {
     // no-op
 }
 
-template <typename TValue, typename TTraceFlag, typename TColumnLocation>
+// overload needed to avoid ambigious overload.
+template <typename TValue, typename THost, typename TTraceFlag>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & /*dpNavigator*/,
-            MetaColumnDescriptor<DPInitialColumn, TColumnLocation> const &,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWiseBanded> & /*dpNavigator*/,
+            MetaColumnDescriptor<DPInitialColumn, PartialColumnTop> const &,
             FirstCell const &)
 {
     // no-op
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                         [PartialColumnTop, FirstCell]
-// ----------------------------------------------------------------------------
-
 // We are in the banded case, where the band crosses the first row.
 // The left cell of the active cell is not valid, beacause we only can come from horizontal direction.
 // The lower left cell of the active cell is the horizontal direction.
-
-template <typename TValue, typename TTraceFlag, typename TColumnType>
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, PartialColumnTop> const &,
             FirstCell const &)
 {
@@ -191,53 +186,108 @@ _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TT
     dpNavigator._activeColIterator += dpNavigator._laneLeap;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell()                       [other column types, FirstCell]
-// ----------------------------------------------------------------------------
-
 // We are in the banded case.
 // The left cell of the active cell represents diagonal direction. The lower left diagonal represents the horizontal direction.
-
-template <typename TValue, typename TTraceFlag, typename TColumnType, typename TColumnLocation>
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnType, typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
             FirstCell const &)
 {
     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;  // Do nothing since no trace back is computed.
 
+    // go to begin of next column.
     dpNavigator._activeColIterator += dpNavigator._laneLeap;
 }
 
 // ----------------------------------------------------------------------------
-// Function _goNextCell                                 [any column, InnerCell]
+// Function _goNextCell()                                 [unbanded, FirstCell]
+// ----------------------------------------------------------------------------
+
+//
+template <typename TValue, typename THost, typename TTraceFlag>
+inline void
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWise> & /*dpNavigator*/,
+            MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
+            FirstCell const &)
+{
+    // no-op
+}
+
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnType>
+inline void
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<TColumnType, FullColumn> const &,
+            FirstCell const &)
+{
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+        return;  // Do nothing since no trace back is computed.
+
+    dpNavigator._activeColIterator += dpNavigator._laneLeap;
+}
+
+// ----------------------------------------------------------------------------
+// Function _goNextCell                                     [banded, InnerCell]
 // ----------------------------------------------------------------------------
 
 // For any other column type and location we can use the same navigation procedure.
-template <typename TValue, typename TTraceFlag, typename TColumnType, typename TColumnLocation>
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnType, typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
             InnerCell const &)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;  // Do nothing since no trace back is computed.
 
     ++dpNavigator._activeColIterator;
 }
 
 // ----------------------------------------------------------------------------
-// Function _goNextCell                         [PartialColumnBottom, LastCell]
+// Function _goNextCell                                   [unbanded, InnerCell]
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TTraceFlag>
+// For any other column type and location we can use the same navigation procedure.
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<TColumnType, FullColumn> const &,
+            InnerCell const &)
+{
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+        return;  // Do nothing since no trace back is computed.
+
+    ++dpNavigator._activeColIterator;
+}
+
+// ----------------------------------------------------------------------------
+// Function _goNextCell                                      [banded, LastCell]
+// ----------------------------------------------------------------------------
+
+template <typename TValue, typename THost, typename TTraceFlag>
+inline void
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom> const &,
             LastCell const &)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;  // Do nothing since no trace back is computed.
 
     ++dpNavigator._activeColIterator;
@@ -245,27 +295,29 @@ _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TT
 
 // If we are in banded case and the band crosses the last row, we have to update
 // the additional leap for the current track.
-template <typename TValue, typename TTraceFlag, typename TColumnType>
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnType>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, PartialColumnBottom> const &,
             LastCell const &)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;  // Do nothing since no trace back is computed.
 
     ++dpNavigator._activeColIterator;
     ++dpNavigator._laneLeap;
 }
 
-// ----------------------------------------------------------------------------
-// Function _goNextCell                            [any other column, LastCell]
-// ----------------------------------------------------------------------------
-
 // If we are in the banded case the left cell of the active represents the diagonal direction.
-template <typename TValue, typename TTraceFlag, typename TColumnType, typename TColumnLocation>
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnType, typename TColumnLocation>
 inline void
-_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWiseBanded> & dpNavigator,
             MetaColumnDescriptor<TColumnType, TColumnLocation> const &,
             LastCell const &)
 {
@@ -276,15 +328,36 @@ _goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TT
 }
 
 // ----------------------------------------------------------------------------
+// Function _goNextCell                                    [unbanded, LastCell]
+// ----------------------------------------------------------------------------
+
+template <typename TValue, typename THost, typename TTraceFlag,
+          typename TColumnType>
+inline void
+_goNextCell(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  NavigateColumnWise> & dpNavigator,
+            MetaColumnDescriptor<TColumnType, FullColumn> const &,
+            LastCell const &)
+{
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+        return;  // Do nothing since no trace back is computed.
+
+    ++dpNavigator._activeColIterator;
+}
+
+// ----------------------------------------------------------------------------
 // Function _traceHorizontal()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TTraceFlag>
+template <typename TValue, typename THost, typename TTraceFlag, typename TNavigationSpec>
 inline void
-_traceHorizontal(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_traceHorizontal(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  TNavigationSpec> & dpNavigator,
                  bool isBandShift)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;  // Do nothing since no trace back is computed.
 
     if (isBandShift)
@@ -298,12 +371,14 @@ _traceHorizontal(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatr
 // Function _traceDiagonal()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TTraceFlag>
+template <typename TValue, typename THost, typename TTraceFlag, typename TNavigationSpec>
 inline void
-_traceDiagonal(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_traceDiagonal(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  TNavigationSpec> & dpNavigator,
                bool isBandShift)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;  // Do nothing since no trace back is computed.
 
     if (isBandShift)
@@ -317,12 +392,14 @@ _traceDiagonal(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix
 // Function _traceVertical()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TTraceFlag>
+template <typename TValue, typename THost, typename TTraceFlag, typename TNavigationSpec>
 inline void
-_traceVertical(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_traceVertical(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  TNavigationSpec> & dpNavigator,
                bool /*isBandShift*/)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;  // Do nothing since no trace back is computed.
 
     dpNavigator._activeColIterator -= _dataFactors(*dpNavigator._ptrDataContainer)[DPMatrixDimension_::VERTICAL];
@@ -332,12 +409,15 @@ _traceVertical(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix
 // Function setToPosition()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TTraceFlag, typename TPosition>
+template <typename TValue, typename THost, typename TTraceFlag, typename TNavigationSpec,
+          typename TPosition>
 inline void
-_setToPosition(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_setToPosition(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  TNavigationSpec> & dpNavigator,
               TPosition const & hostPosition)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;
 
     SEQAN_ASSERT_LT(hostPosition, static_cast<TPosition>(length(container(dpNavigator))));
@@ -349,13 +429,16 @@ _setToPosition(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix
 // Sets the host position based on the given horizontal and vertical position. Note that the horizontal and
 // vertical positions must correspond to the correct size of the underlying matrix.
 // For banded matrices the vertical dimension might not equal the length of the vertical sequence.
-template <typename TValue, typename TTraceFlag, typename TPositionH, typename TPositionV>
+template <typename TValue, typename THost, typename TTraceFlag, typename TNavigationSpec,
+          typename TPositionH, typename TPositionV>
 inline void
-_setToPosition(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix<TTraceFlag>, NavigateColumnWise> & dpNavigator,
+_setToPosition(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix, THost>,
+                                  DPTraceMatrix<TTraceFlag>,
+                                  TNavigationSpec> & dpNavigator,
               TPositionH const & horizontalPosition,
               TPositionV const & verticalPosition)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;
     SEQAN_ASSERT_LT(horizontalPosition, static_cast<TPositionH>(length(container(dpNavigator), +DPMatrixDimension_::HORIZONTAL)));
     SEQAN_ASSERT_LT(verticalPosition, static_cast<TPositionV>(length(container(dpNavigator), +DPMatrixDimension_::VERTICAL)));
@@ -368,12 +451,13 @@ _setToPosition(DPMatrixNavigator_<DPMatrix_<TValue, FullDPMatrix>, DPTraceMatrix
 // Function assignValue()
 // ----------------------------------------------------------------------------
 
-template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec, typename TValue>
+template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec,
+          typename TValue>
 inline void
 assignValue(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> & dpNavigator,
             TValue const & element)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return;  // Do nothing since no trace back is computed.
 
     *dpNavigator._activeColIterator = element;
@@ -385,7 +469,7 @@ assignValue(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigation
 
 // SIMD Version. Returns always a copy and never a reference.
 template <typename TValue, typename TPos>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TValue> >, typename Value<TValue>::Type)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TValue> >, typename TraceBitMap_<>::Type)
 _scalarValue(TValue const & vec,
              TPos const pos)
 {
@@ -394,7 +478,7 @@ _scalarValue(TValue const & vec,
 
 // Non-simd variant. Identity version.
 template <typename TValue, typename TPos>
-inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TValue> > >, TValue &)
+inline SEQAN_FUNC_ENABLE_IF(Not<Is<SimdVectorConcept<TValue> > >, TValue)
 _scalarValue(TValue & val,
              TPos const /*pos*/)
 {
@@ -406,7 +490,7 @@ template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec>
 inline auto
 scalarValue(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
 
     return _scalarValue(*dpNavigator._activeColIterator, dpNavigator._simdLane);
@@ -421,7 +505,7 @@ template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec>
 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> >::Type
 value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> & dpNavigator)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
 
     return *dpNavigator._activeColIterator;
@@ -431,7 +515,7 @@ template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec>
 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const >::Type
 value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
 
     return *dpNavigator._activeColIterator;
@@ -443,18 +527,19 @@ inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag
 value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> & dpNavigator,
       TPosition const & position)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
 
     return *(begin(*dpNavigator._ptrDataContainer) + position);
 }
 
-template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec, typename TPosition>
+template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec,
+          typename TPosition>
 inline typename Reference<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const >::Type
 value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator,
       TPosition const & position)
 {
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
 
     return *(begin(*dpNavigator._ptrDataContainer) + position);
@@ -467,21 +552,42 @@ value(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec>
 // Returns the coordinate of the given dimension for the current position of the
 // navigator within the matrix.
 template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec>
-inline typename DPMatrixDimension_::TValue
+inline size_t
 coordinate(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator,
            typename DPMatrixDimension_::TValue const & dimension)
 {
     if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
-        SEQAN_ASSERT_FAIL("Try to access uninitialized object!");
+        return 0;  // Returns default 0, when traceback is set off.
     SEQAN_ASSERT_EQ(_checkCorrectDimension(dimension), true);
 
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return _dataLengths(*dpNavigator._ptrDataContainer)[dimension];  // Return lengths of given dimension.
 
     return coordinate(value(dpNavigator._ptrDataContainer), position(dpNavigator), dimension); // Simply delegate to coordinate of underlying matrix.
 }
 
 // ----------------------------------------------------------------------------
+// Function toGlobalPosition()
+// ----------------------------------------------------------------------------
+
+// Returns the current position of the navigator within the matrix.
+template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec,
+          typename TPosH,
+          typename TPosV>
+inline typename Position<DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> >::Type
+toGlobalPosition(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> const & dpNavigator,
+                 TPosH const horizontalCoordinate,
+                 TPosV const verticalCoordinate)
+{
+    // Return 0 when traceback is not enabled. This is necessary to still track the score even
+    // the traceback is not enabled.
+    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+        return 0;
+
+    return  toGlobalPosition(*dpNavigator._ptrDataContainer, horizontalCoordinate, verticalCoordinate);
+}
+
+// ----------------------------------------------------------------------------
 // Function position()
 // ----------------------------------------------------------------------------
 
@@ -492,7 +598,7 @@ position(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpe
 {
     // Return 0 when traceback is not enabled. This is necessary to still track the score even
     // the traceback is not enabled.
-    if (IsSameType<TTraceFlag, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTraceFlag, TracebackOff>::VALUE)
         return 0;
 
     return position(dpNavigator._activeColIterator, *dpNavigator._ptrDataContainer);
@@ -502,7 +608,8 @@ position(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpe
 // Function _setSimdLane()
 // ----------------------------------------------------------------------------
 
-template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec, typename TPos>
+template <typename TDPMatrix, typename TTraceFlag, typename TNavigationSpec,
+          typename TPos>
 inline void
 _setSimdLane(DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TTraceFlag>, TNavigationSpec> & dpNavigator,
              TPos const pos)
diff --git a/include/seqan/align/dp_matrix_sparse.h b/include/seqan/align/dp_matrix_sparse.h
index 4666a46..8605bb7 100644
--- a/include/seqan/align/dp_matrix_sparse.h
+++ b/include/seqan/align/dp_matrix_sparse.h
@@ -49,14 +49,14 @@ namespace seqan {
 // Class DPMatrix                                              [SparseDPMatrix]
 // ----------------------------------------------------------------------------
 
-template <typename TValue>
-class DPMatrix_<TValue, SparseDPMatrix>
+template <typename TValue, typename THost>
+class DPMatrix_<TValue, SparseDPMatrix, THost>
 {
 public:
 
-    typedef typename Member<DPMatrix_, DPMatrixMember>::Type THost;
+    typedef typename Member<DPMatrix_, DPMatrixMember>::Type TMatrix;
 
-    Holder<THost>   data_host;  // The host containing the actual matrix.
+    Holder<TMatrix>   data_host;  // The host containing the actual matrix.
 
     DPMatrix_() :
         data_host()
@@ -77,11 +77,11 @@ public:
 // Function resize()
 // ----------------------------------------------------------------------------
 
-template <typename TValue>
+template <typename TValue, typename THost>
 inline void
-resize(DPMatrix_<TValue, SparseDPMatrix> & dpMatrix)
+resize(DPMatrix_<TValue, SparseDPMatrix, THost> & dpMatrix)
 {
-    typedef DPMatrix_<TValue, SparseDPMatrix> TDPMatrix;
+    typedef DPMatrix_<TValue, SparseDPMatrix, THost> TDPMatrix;
     typedef typename Size<TDPMatrix>::Type TSize;
 
     TSize _dimVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL);
@@ -90,12 +90,12 @@ resize(DPMatrix_<TValue, SparseDPMatrix> & dpMatrix)
         resize(host(dpMatrix), _dimVertical, Exact());
 }
 
-template <typename TValue>
+template <typename TValue, typename THost>
 inline void
-resize(DPMatrix_<TValue, SparseDPMatrix> & dpMatrix,
+resize(DPMatrix_<TValue, SparseDPMatrix, THost> & dpMatrix,
        TValue const & fillValue)
 {
-    typedef DPMatrix_<TValue, SparseDPMatrix> TDPMatrix;
+    typedef DPMatrix_<TValue, SparseDPMatrix, THost> TDPMatrix;
     typedef typename Size<TDPMatrix>::Type TSize;
 
     TSize _dimVertical = length(dpMatrix, DPMatrixDimension_::VERTICAL);
@@ -108,18 +108,18 @@ resize(DPMatrix_<TValue, SparseDPMatrix> & dpMatrix,
 // Function value()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TPositionV, typename TPositionH>
-inline typename Reference<DPMatrix_<TValue, SparseDPMatrix> >::Type
-value(DPMatrix_<TValue, SparseDPMatrix> & dpMatrix,
+template <typename TValue, typename THost, typename TPositionV, typename TPositionH>
+inline typename Reference<DPMatrix_<TValue, SparseDPMatrix, THost> >::Type
+value(DPMatrix_<TValue, SparseDPMatrix, THost> & dpMatrix,
       TPositionV const & posV,
       TPositionH const &)
 {
     return value(dpMatrix, posV);
 }
 
-template <typename TValue, typename TPositionV, typename TPositionH>
-inline typename Reference<DPMatrix_<TValue, SparseDPMatrix> const>::Type
-value(DPMatrix_<TValue, SparseDPMatrix> const & dpMatrix,
+template <typename TValue, typename THost, typename TPositionV, typename TPositionH>
+inline typename Reference<DPMatrix_<TValue, SparseDPMatrix, THost> const>::Type
+value(DPMatrix_<TValue, SparseDPMatrix, THost> const & dpMatrix,
       TPositionV const & posV,
       TPositionH const &)
 {
@@ -131,9 +131,9 @@ value(DPMatrix_<TValue, SparseDPMatrix> const & dpMatrix,
 // ----------------------------------------------------------------------------
 
 
-template <typename TValue, typename TPosition>
-inline typename Position<DPMatrix_<TValue, SparseDPMatrix> >::Type
-coordinate(DPMatrix_<TValue, SparseDPMatrix> const & /*dpMatrix*/,
+template <typename TValue, typename THost, typename TPosition>
+inline typename Position<DPMatrix_<TValue, SparseDPMatrix, THost> >::Type
+coordinate(DPMatrix_<TValue, SparseDPMatrix, THost> const & /*dpMatrix*/,
            TPosition hostPos,
            typename DPMatrixDimension_::TValue dimension)
 {
diff --git a/include/seqan/align/dp_profile.h b/include/seqan/align/dp_profile.h
index a861e37..1580b38 100644
--- a/include/seqan/align/dp_profile.h
+++ b/include/seqan/align/dp_profile.h
@@ -80,7 +80,7 @@ typedef Tag<AlignmentSplitBreakpoint_> SplitBreakpointAlignment;
 //
 // Note, all global alignments have to be specialized versions of GlobalAlignment_<>
 template <typename TSpec = FreeEndGaps_<> >
-struct GlobalAlignment_;
+struct GlobalAlignment_{};
 
 typedef GlobalAlignment_<> DPGlobal;
 
@@ -103,73 +103,82 @@ typedef Tag<AlignmentSuboptimal_> SuboptimalAlignment;
 // Note, all local alignments have to be specialized versions of LocalAlignment_<>
 
 template <typename TSpec = Default>
-struct LocalAlignment_;
+struct LocalAlignment_{};
 
 typedef LocalAlignment_<> DPLocal;
 typedef LocalAlignment_<SuboptimalAlignment> DPLocalEnumerate;
 
-// Use macro expansion to define all possible SIMD initialization types.
-
-template <typename TVector, uint8_t FILL_VALUE, unsigned SIZE>
-struct InitSimdTrace_;
-
-#define SEQAN_SIMD_INIT_FILL_VALUE_2_ FILL_VALUE, FILL_VALUE
-#define SEQAN_SIMD_INIT_FILL_VALUE_4_ SEQAN_SIMD_INIT_FILL_VALUE_2_, SEQAN_SIMD_INIT_FILL_VALUE_2_
-#define SEQAN_SIMD_INIT_FILL_VALUE_8_ SEQAN_SIMD_INIT_FILL_VALUE_4_, SEQAN_SIMD_INIT_FILL_VALUE_4_
-#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_t FILL_VALUE>                                                     \
-struct InitSimdTrace_<TVector, FILL_VALUE, SIZE>                                                    \
-{                                                                                                   \
-    static const TVector VALUE;                                                                     \
-};                                                                                                  \
-                                                                                                    \
-template <typename TVector, uint8_t 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_t FILL_VALUE>                                                     \
-struct InitSimdTrace_<TVector, FILL_VALUE, SIZE>                                                    \
-{                                                                                                   \
-    static const TVector VALUE;                                                                     \
-};                                                                                                  \
-                                                                                                    \
-template <typename TVector, uint8_t 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 ## _)
-
-SEQAN_SIMD_TRACE_SETUP_(2)
-SEQAN_SIMD_TRACE_SETUP_(4)
-SEQAN_SIMD_TRACE_SETUP_(8)
-SEQAN_SIMD_TRACE_SETUP_(16)
-SEQAN_SIMD_TRACE_SETUP_(32)
-
-// Scalar version.
+// ----------------------------------------------------------------------------
+// Class TraceBitMap_
+// ----------------------------------------------------------------------------
+
+// Defines static const/constexpr tables for the traceback directions.
+// We use TraceValue_ as a helper to distinguish between vector and
+// scalar version.
+// For the vector version we use some compile time hackery to initialize the
+// const vector values with the corresponding values generically for
+// seqan simd vector types and UME::SIMD vector types.
 template <typename TValue, typename TIsSimdVector>
 struct TraceValue_
 {
     typedef uint8_t Type;
-    static const Type NONE = 0u;                         //0000000
-    static const Type DIAGONAL = 1u;                     //0000001
-    static const Type HORIZONTAL = 2u;                   //0000010
-    static const Type VERTICAL = 4u;                     //0000100
-    static const Type HORIZONTAL_OPEN = 8u;              //0001000
-    static const Type VERTICAL_OPEN = 16u;               //0010000
-    static const Type MAX_FROM_HORIZONTAL_MATRIX = 32u;  //0100000
-    static const Type MAX_FROM_VERTICAL_MATRIX = 64u;    //1000000
-    static const Type NO_VERTICAL_TRACEBACK = ~(VERTICAL | VERTICAL_OPEN);
-    static const Type NO_HORIZONTAL_TRACEBACK = ~(HORIZONTAL | HORIZONTAL_OPEN);
+    static constexpr Type NONE = 0u;                         //0000000
+    static constexpr Type DIAGONAL = 1u;                     //0000001
+    static constexpr Type HORIZONTAL = 2u;                   //0000010
+    static constexpr Type VERTICAL = 4u;                     //0000100
+    static constexpr Type HORIZONTAL_OPEN = 8u;              //0001000
+    static constexpr Type VERTICAL_OPEN = 16u;               //0010000
+    static constexpr Type MAX_FROM_HORIZONTAL_MATRIX = 32u;  //0100000
+    static constexpr Type MAX_FROM_VERTICAL_MATRIX = 64u;    //1000000
+    static constexpr Type NO_VERTICAL_TRACEBACK = ~(VERTICAL | VERTICAL_OPEN);
+    static constexpr Type NO_HORIZONTAL_TRACEBACK = ~(HORIZONTAL | HORIZONTAL_OPEN);
 };
 
-// SIMD Vector version.
-template <typename TVector>
-struct TraceValue_<TVector, True>
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::NONE;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::DIAGONAL;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::HORIZONTAL;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::VERTICAL;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::HORIZONTAL_OPEN;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::VERTICAL_OPEN;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::MAX_FROM_HORIZONTAL_MATRIX;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::MAX_FROM_VERTICAL_MATRIX;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::NO_VERTICAL_TRACEBACK;
+template <typename TValue, typename TIsSimdVector>
+constexpr typename TraceValue_<TValue, TIsSimdVector>::Type TraceValue_<TValue, TIsSimdVector>::NO_HORIZONTAL_TRACEBACK;
+
+// Recursion anchor to return the generated tuple with all fill values.
+template <typename ...TValues>
+constexpr auto _fillTraceValueVector(std::index_sequence<0> const &, std::tuple<TValues...> const & t)
+{
+    return t;
+}
+
+// Helper function to fill the vector with the correct number of values.
+// We use the std::tuple (which supports constexpr functions) to make it evaluate at compile time.
+template <size_t ...I, typename ...TValues>
+constexpr auto _fillTraceValueVector(std::index_sequence<I...> const &, std::tuple<TValues...> const & t)
+{
+    // Expand the tuple by one and return the next tuple while reducing the number of elements to add.
+    return _fillTraceValueVector(std::make_index_sequence<sizeof...(I) - 1>{},
+                                 std::tuple_cat(std::make_tuple(std::get<0>(t)), t));
+}
+
+// Helper class to used to expand the elements from the returned tuple with the fill values.
+// NOTE(rrahn): Might be easier to solve with fold expressions in SeqAn3.
+template <typename TVector, typename TIndexSequence>
+struct TraceValueVectorBase_;
+
+template <typename TVector, size_t ...I>
+struct TraceValueVectorBase_<TVector, std::index_sequence<I...>>
 {
     typedef TVector Type;
     static const Type NONE;
@@ -184,26 +193,46 @@ struct TraceValue_<TVector, True>
     static const Type NO_VERTICAL_TRACEBACK;
 };
 
-// Macro expansion to define out-of-class initialization of static members.
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::NONE =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::NONE)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::DIAGONAL =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::DIAGONAL)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::HORIZONTAL =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::HORIZONTAL)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::VERTICAL =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::VERTICAL)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::HORIZONTAL_OPEN =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::HORIZONTAL_OPEN)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::VERTICAL_OPEN =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::VERTICAL_OPEN)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::MAX_FROM_HORIZONTAL_MATRIX =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::MAX_FROM_HORIZONTAL_MATRIX)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::MAX_FROM_VERTICAL_MATRIX =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::MAX_FROM_VERTICAL_MATRIX)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::NO_VERTICAL_TRACEBACK =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::NO_HORIZONTAL_TRACEBACK)))...};
+template <typename TVector, size_t ...I>
+const typename TraceValueVectorBase_<TVector, std::index_sequence<I...>>::Type TraceValueVectorBase_<TVector, std::index_sequence<I...>>::NO_HORIZONTAL_TRACEBACK =
+    {std::get<I>(_fillTraceValueVector(std::make_index_sequence<LENGTH<TVector>::VALUE>{}, std::make_tuple(TraceValue_<uint8_t, False>::NO_VERTICAL_TRACEBACK)))...};
 
-#define SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(TRACE_VALUE)                             \
-    template <typename TVector>                                                      \
-    const TVector TraceValue_<TVector, True>::TRACE_VALUE = InitSimdTrace_<TVector, TraceValue_<uint8_t, False>::TRACE_VALUE, LENGTH<TVector>::VALUE>::VALUE;
-
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(NONE)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(DIAGONAL)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(HORIZONTAL)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(VERTICAL)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(HORIZONTAL_OPEN)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(VERTICAL_OPEN)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(MAX_FROM_HORIZONTAL_MATRIX)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(MAX_FROM_VERTICAL_MATRIX)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(NO_HORIZONTAL_TRACEBACK)
-SEQAN_SIMD_TRACE_OUT_OF_CLASS_INIT_(NO_VERTICAL_TRACEBACK)
+// SIMD Vector version.
+// Simply delegates to the base class by passing the index_sequence with the corresponding length of the vector.
+template <typename TVector>
+struct TraceValue_<TVector, True> : public TraceValueVectorBase_<TVector, std::make_index_sequence<LENGTH<TVector>::VALUE>>
+{};
 
 // Type alias to choose between scalar and simd version of trace value.
 template <typename TValue = uint8_t>
-using TraceBitMap_ = TraceValue_<TValue, typename Is<SimdVectorConcept<TValue> >::Type >;
+using TraceBitMap_ = TraceValue_<TValue, typename Is<SimdVectorConcept<TValue> >::Type>;
 
 // ----------------------------------------------------------------------------
 // Tag GapsLeft
@@ -310,10 +339,9 @@ typedef Tag<DynamicGaps_> DynamicGaps;
 // TAlignment: The type to select the pairwise alignment algorithm.
 // TGapCosts:  The gap cost function (LinearGaps or AffineGaps).
 // TTraceback: The traceback switch (TracebackOn or TracebackOff).
-template <typename TAlignment, typename TGapCosts, typename TTraceback>
+template <typename TAlignment, typename TGapCosts, typename TTraceback, typename TExecPolicy = Serial>
 struct DPProfile_ {};
 
-
 // ----------------------------------------------------------------------------
 // Tag DPFirstRow
 // ----------------------------------------------------------------------------
@@ -363,6 +391,63 @@ public:
 // Metafunctions
 // ============================================================================
 
+enum class DPProfileTypeId : uint8_t
+{
+    ALGORITHM = 0,
+    GAP_MODEL = 1,
+    TRACE_CONFIG = 2,
+    EXEC_POLICY = 3
+};
+
+// ----------------------------------------------------------------------------
+// Metafunction DPContextSpec
+// ----------------------------------------------------------------------------
+
+template <typename TDPProfile, DPProfileTypeId ID>
+struct DPProfileType;
+
+template <typename TAlignment, typename TGapCosts, typename TTraceback, typename TExecPolicy>
+struct DPProfileType<DPProfile_<TAlignment, TGapCosts, TTraceback, TExecPolicy>, DPProfileTypeId::ALGORITHM>
+{
+    using Type = TAlignment;
+};
+
+template <typename TAlignment, typename TGapCosts, typename TTraceback, typename TExecPolicy>
+struct DPProfileType<DPProfile_<TAlignment, TGapCosts, TTraceback, TExecPolicy>, DPProfileTypeId::GAP_MODEL>
+{
+    using Type = TGapCosts;
+};
+
+template <typename TAlignment, typename TGapCosts, typename TTraceback, typename TExecPolicy>
+struct DPProfileType<DPProfile_<TAlignment, TGapCosts, TTraceback, TExecPolicy>, DPProfileTypeId::TRACE_CONFIG>
+{
+    using Type = TTraceback;
+};
+
+template <typename TAlignment, typename TGapCosts, typename TTraceback, typename TExecPolicy>
+struct DPProfileType<DPProfile_<TAlignment, TGapCosts, TTraceback, TExecPolicy>, DPProfileTypeId::EXEC_POLICY>
+{
+    using Type = TExecPolicy;
+};
+
+// ----------------------------------------------------------------------------
+// Metafunction GapTraits
+// ----------------------------------------------------------------------------
+
+template <typename T>
+struct GapTraits;
+
+template <typename T>
+struct GapTraits<T const> :
+    GapTraits<T>
+{};
+
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct GapTraits<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> >
+{
+    typedef TGapCosts Type;
+};
+
 // ----------------------------------------------------------------------------
 // Metafunction IsGlobalAlignment
 // ----------------------------------------------------------------------------
@@ -380,12 +465,12 @@ template <typename TSpec>
 struct IsGlobalAlignment_<GlobalAlignment_<TSpec> const>:
     True {};
 
-template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag>
-struct IsGlobalAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag> >:
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct IsGlobalAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> >:
     IsGlobalAlignment_<TAlgoSpec>{};
 
-template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag>
-struct IsGlobalAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag> const>:
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct IsGlobalAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> const>:
     IsGlobalAlignment_<TAlgoSpec>{};
 
 // ----------------------------------------------------------------------------
@@ -434,12 +519,12 @@ template <typename TSpec>
 struct IsLocalAlignment_<LocalAlignment_<TSpec> const>:
     True {};
 
-template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag>
-struct IsLocalAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag> >:
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct IsLocalAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> >:
     IsLocalAlignment_<TAlgoSpec>{};
 
-template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag>
-struct IsLocalAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag> const>:
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct IsLocalAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> const>:
     IsLocalAlignment_<TAlgoSpec>{};
 
 // ----------------------------------------------------------------------------
@@ -459,12 +544,12 @@ template <typename TTracebackConfig>
 struct IsTracebackEnabled_<TracebackOn<TTracebackConfig> const>:
     True {};
 
-template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag>
-struct IsTracebackEnabled_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag> >:
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct IsTracebackEnabled_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> >:
     IsTracebackEnabled_<TTraceFlag>{};
 
-template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag>
-struct IsTracebackEnabled_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag> const>:
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct IsTracebackEnabled_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> const>:
     IsTracebackEnabled_<TTraceFlag>{};
 
 // ----------------------------------------------------------------------------
@@ -478,8 +563,8 @@ template <typename TTraceSpec>
 struct IsGapsLeft_<TracebackOn<TracebackConfig_<TTraceSpec, GapsLeft > > >
         : True{};
 
-template <typename TAlgorithm, typename TGapSpec, typename TTraceConfig>
-struct IsGapsLeft_<DPProfile_<TAlgorithm, TGapSpec, TTraceConfig> >
+template <typename TAlgorithm, typename TGapSpec, typename TTraceConfig, typename TExecPolicy>
+struct IsGapsLeft_<DPProfile_<TAlgorithm, TGapSpec, TTraceConfig, TExecPolicy> >
         : IsGapsLeft_<TTraceConfig>{};
 
 // ----------------------------------------------------------------------------
@@ -487,15 +572,16 @@ struct IsGapsLeft_<DPProfile_<TAlgorithm, TGapSpec, TTraceConfig> >
 // ----------------------------------------------------------------------------
 
 template <typename TTraceConfig>
-struct IsSingleTrace_ : False{};
+struct IsSingleTrace_ : False
+{};
 
 template <typename TGapsPlacement>
-struct IsSingleTrace_<TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > >
-: True{};
+struct IsSingleTrace_<TracebackOn<TracebackConfig_<SingleTrace, TGapsPlacement> > > : True
+{};
 
-template <typename TAlgorithm, typename TGapSpec, typename TTraceConfig>
-struct IsSingleTrace_<DPProfile_<TAlgorithm, TGapSpec, TTraceConfig> >
-: IsSingleTrace_<TTraceConfig>{};
+template <typename TAlgorithm, typename TGapSpec, typename TTraceConfig, typename TExecPolicy>
+struct IsSingleTrace_<DPProfile_<TAlgorithm, TGapSpec, TTraceConfig, TExecPolicy> > : IsSingleTrace_<TTraceConfig>
+{};
 
 // ----------------------------------------------------------------------------
 // Metafunction IsFreeEndGap_
@@ -506,12 +592,12 @@ template <typename TAlignmentSpec, typename TDPSide>
 struct IsFreeEndGap_ :
     False {};
 
-template <typename TAlignmentSpec, typename TGapSpec, typename TTracebackSpec, typename TDPSide>
-struct IsFreeEndGap_<DPProfile_<TAlignmentSpec, TGapSpec, TTracebackSpec> const, TDPSide>:
+template <typename TAlignmentSpec, typename TGapSpec, typename TTracebackSpec, typename TExecPolicy, typename TDPSide>
+struct IsFreeEndGap_<DPProfile_<TAlignmentSpec, TGapSpec, TTracebackSpec, TExecPolicy> const, TDPSide>:
     IsFreeEndGap_<TAlignmentSpec, TDPSide>{};
 
-template <typename TAlignmentSpec, typename TGapSpec, typename TTracebackSpec, typename TDPSide>
-struct IsFreeEndGap_<DPProfile_<TAlignmentSpec, TGapSpec, TTracebackSpec>, TDPSide>:
+template <typename TAlignmentSpec, typename TGapSpec, typename TTracebackSpec, typename TExecPolicy, typename TDPSide>
+struct IsFreeEndGap_<DPProfile_<TAlignmentSpec, TGapSpec, TTracebackSpec, TExecPolicy>, TDPSide>:
     IsFreeEndGap_<TAlignmentSpec, TDPSide>{};
 
 template <typename TLocalSpec, typename TDPSide>
@@ -578,6 +664,27 @@ struct IsFreeEndGap_<FreeEndGaps_<TFirstRow, TFirstColumn, TLastRow, True> const
 // Functions
 // ============================================================================
 
+namespace impl
+{
+    template <typename TStream>
+    inline TStream &
+    printTraceValue(TStream & stream, char traceValue)
+    {
+        if (traceValue & (TraceBitMap_<char>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<char>::VERTICAL))
+        {
+            stream << "|";
+        }
+        if (traceValue & (TraceBitMap_<char>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<char>::HORIZONTAL))
+        {
+            stream << "-";
+        }
+        if (traceValue & TraceBitMap_<char>::DIAGONAL)
+        {
+            stream << "\\";
+        }
+        return stream;
+    }
+}  // namespace impl
 }  // namespace seqan
 
 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_PROFILE_H_
diff --git a/include/seqan/align/dp_scout.h b/include/seqan/align/dp_scout.h
index 4642f9d..8d88aea 100644
--- a/include/seqan/align/dp_scout.h
+++ b/include/seqan/align/dp_scout.h
@@ -93,10 +93,11 @@ template <typename TDPCell, typename TSpec>
 class DPScout_
 {
 public:
+    using TBase = DPScout_;
     using TScoreValue = typename Value<TDPCell>::Type;
 
     TDPCell _maxScore         = TDPCell();
-    uint32_t _maxHostPosition = DPCellDefaultInfinity<TScoreValue>::VALUE; // The corresponding host position within the underlying dp-matrix.
+    size_t _maxHostPosition   = 0; // The corresponding host position within the underlying dp-matrix.
 
     DPScout_() = default;
 
@@ -109,7 +110,7 @@ class DPScout_<TDPCell, Terminator_<TSpec> >
     : public DPScout_<TDPCell, Default>
 {
 public:
-    typedef DPScout_<TDPCell, Default>  TParent;
+    using TBase = DPScout_<TDPCell, Default>;
 
     DPScoutState_<Terminator_<TSpec> > * state = nullptr;
     bool terminationCriteriumMet               = false;
@@ -117,7 +118,7 @@ public:
     DPScout_() = default;
 
     DPScout_(DPScoutState_<Terminator_<TSpec> > & pState) :
-        DPScout_<TDPCell, Default>(),
+        TBase(),
         state(&pState)
     {}
 };
@@ -217,7 +218,7 @@ maxScore(DPScout_<TDPCell, TScoutSpec> const & dpScout)
 
 // Returns the host position that holds the current maximum score.
 template <typename TDPCell, typename TScoutSpec>
-inline unsigned int
+inline auto
 maxHostPosition(DPScout_<TDPCell, TScoutSpec> const & dpScout)
 {
     return dpScout._maxHostPosition;
@@ -335,6 +336,21 @@ _incVerticalPos(DPScout_<TDPCell, TSpec> const & /*scout*/)
     // no-op.
 }
 
+// ----------------------------------------------------------------------------
+//  Function swapStateIf()
+// ----------------------------------------------------------------------------
+
+template <typename TSingleMaxState, typename TPredicate>
+inline bool swapStateIf(TSingleMaxState && lhs, TSingleMaxState && rhs, TPredicate && p)
+{
+    using std::swap;
+
+    if (!p(lhs.mMaxScore, rhs.mMaxScore))
+        return false;
+    swap(lhs, rhs);
+    return true;
+}
+
 }  // namespace seqan
 
 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_TEST_ALIGNMENT_DP_SCOUT_H_
diff --git a/include/seqan/align/dp_scout_simd.h b/include/seqan/align/dp_scout_simd.h
index a7615a8..64c9ddd 100644
--- a/include/seqan/align/dp_scout_simd.h
+++ b/include/seqan/align/dp_scout_simd.h
@@ -93,16 +93,12 @@ class DPScout_<TDPCell, SimdAlignmentScout<TSpec> > :
     public DPScout_<TDPCell, Default>
 {
 public:
+    using TSimdVec    = typename Value<TDPCell>::Type;
     using TBase       = DPScout_<TDPCell, Default>;
     using TScoutState = DPScoutState_<TSpec>;
 
-    //used in the SIMD version to keep track of all host positions
-    //SIMD register size divided by 16bit is the amount of alignments
-    //so we need two vectors of type 32bit to save the host for all alignments
-
-    // TODO(rrahn): Abstract into a struct, so we can model different configurations.
-    SimdVector<int32_t>::Type _maxHostLow; //first half of alignments
-    SimdVector<int32_t>::Type _maxHostHigh; //other half
+    TSimdVec    mHorizontalPos;
+    TSimdVec    mVerticalPos;
     TScoutState * state = nullptr;
     unsigned _simdLane  = 0;
 
@@ -138,31 +134,40 @@ struct ScoutSpecForAlignmentAlgorithm_<TAlignmentAlgorithm, DPScoutState_<SimdAl
 // Function _copySimdCell()
 // ----------------------------------------------------------------------------
 
-template <typename TValue, typename TSpec, typename TScoreValue>
+template <typename TValue, typename TGapSpec, typename TSpec,
+          typename TScoreValue,
+          typename TTraceConfig>
 inline void
-_copySimdCell(DPScout_<DPCell_<TValue, LinearGaps>, SimdAlignmentScout<TSpec> > & dpScout,
-              DPCell_<TValue, LinearGaps> const & activeCell,
-              TScoreValue const & cmp)
+_copySimdCell(DPScout_<DPCell_<TValue, TGapSpec>, SimdAlignmentScout<TSpec> > & dpScout,
+              DPCell_<TValue, TGapSpec> const & activeCell,
+              TScoreValue const & cmp,
+              DPTraceMatrix<TTraceConfig> const & /**/)
 {
     dpScout._maxScore._score = blend(dpScout._maxScore._score, activeCell._score, cmp);
 }
 
-template <typename TValue, typename TSpec, typename TScoreValue>
+template <typename TValue, typename TSpec,
+          typename TScoreValue,
+          typename TTraceConfig>
 inline void
 _copySimdCell(DPScout_<DPCell_<TValue, AffineGaps>, SimdAlignmentScout<TSpec> > & dpScout,
               DPCell_<TValue, AffineGaps> const & activeCell,
-              TScoreValue const & cmp)
+              TScoreValue const & cmp,
+              DPTraceMatrix<TracebackOn<TTraceConfig>> const & /**/)
 {
     dpScout._maxScore._score = blend(dpScout._maxScore._score, activeCell._score, cmp);
     dpScout._maxScore._horizontalScore = blend(dpScout._maxScore._horizontalScore, activeCell._horizontalScore, cmp);
     dpScout._maxScore._verticalScore = blend(dpScout._maxScore._verticalScore, activeCell._verticalScore, cmp);
 }
 
-template <typename TValue, typename TSpec, typename TScoreValue>
+template <typename TValue, typename TSpec,
+          typename TScoreValue,
+          typename TTraceConfig, typename TGapsPlacement>
 inline void
 _copySimdCell(DPScout_<DPCell_<TValue, DynamicGaps>, SimdAlignmentScout<TSpec> > & dpScout,
               DPCell_<TValue, DynamicGaps> const & activeCell,
-              TScoreValue const & cmp)
+              TScoreValue const & cmp,
+              DPTraceMatrix<TracebackOn<TTraceConfig>> const & /**/)
 {
     dpScout._maxScore._score = blend(dpScout._maxScore._score, activeCell._score, cmp);
     dpScout._maxScore._flagMask = blend(dpScout._maxScore._flagMask, activeCell._flagMask, cmp);
@@ -172,40 +177,45 @@ _copySimdCell(DPScout_<DPCell_<TValue, DynamicGaps>, SimdAlignmentScout<TSpec> >
 // Function _updateHostPositions()
 // ----------------------------------------------------------------------------
 
-template<typename TDPCell, typename TScoutSpec, typename TSimdVec>
+// No trace needed, hence we do not track the max positions.
+template<typename TDPCell, typename TScoutSpec,
+         typename TMask,
+         typename TNavigator>
+inline void
+_updateHostPositions(DPScout_<TDPCell, TScoutSpec> & /*dpScout*/,
+                     TMask const & /*cmp*/,
+                     TNavigator const & /*navi*/,
+                     DPTraceMatrix<TracebackOff> const & /**/)
+{}
+
+template<typename TDPCell, typename TScoutSpec,
+         typename TMask,
+         typename TNavigator,
+         typename TTraceConfig>
 inline void
 _updateHostPositions(DPScout_<TDPCell, TScoutSpec> & dpScout,
-                     TSimdVec & cmp,
-                     SimdVector<int32_t>::Type positionNavigator)
-{
-// TODO(rrahn): Refactor!
-#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,
-                                 _mm256_cvtepi16_epi32(_mm256_extractf128_si256(reinterpret_cast<__m256i&>(cmp),1)));
-#elif defined(__SSE3__)
-    dpScout._maxHostLow = blend(dpScout._maxHostLow, positionNavigator,
-                                _mm_unpacklo_epi16(reinterpret_cast<__m128i&>(cmp), reinterpret_cast<__m128i&>(cmp)));
-    dpScout._maxHostHigh = blend(dpScout._maxHostHigh, positionNavigator,
-                                 _mm_unpackhi_epi16(reinterpret_cast<__m128i&>(cmp), reinterpret_cast<__m128i&>(cmp)));
-#endif
+                     TMask const & cmp,
+                     TNavigator const & navi,
+                     DPTraceMatrix<TTraceConfig> const & /**/)
+{
+    using TSimdVector = typename Value<TDPCell>::Type;
+    dpScout.mHorizontalPos = blend(dpScout.mHorizontalPos,
+                                   createVector<TSimdVector>(coordinate(navi, +DPMatrixDimension_::HORIZONTAL)),
+                                   cmp);
+
+    dpScout.mVerticalPos = blend(dpScout.mVerticalPos,
+                                 createVector<TSimdVector>(coordinate(navi, +DPMatrixDimension_::VERTICAL)),
+                                 cmp);
 }
 
 // ----------------------------------------------------------------------------
 // Function _scoutBestScore()                            [SimdAlignEqualLength]
 // ----------------------------------------------------------------------------
 
-template <typename TDPCell, typename TTraceMatrixNavigator, typename TIsLastColumn, typename TIsLastRow>
+template <typename TDPCell,
+          typename TTraceMatrixNavigator,
+          typename TIsLastColumn,
+          typename TIsLastRow>
 inline void
 _scoutBestScore(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignEqualLength> > & dpScout,
                 TDPCell const & activeCell,
@@ -213,9 +223,61 @@ _scoutBestScore(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignEqualLength> > & d
                 TIsLastColumn const & /**/,
                 TIsLastRow const & /**/)
 {
+    using TMatrixType = typename MatrixType<TTraceMatrixNavigator>::Type;
     auto cmp = cmpGt(_scoreOfCell(activeCell), _scoreOfCell(dpScout._maxScore));
-    _copySimdCell(dpScout, activeCell, cmp);
-    _updateHostPositions(dpScout, cmp, createVector<SimdVector<int32_t>::Type>(position(navigator)));
+    _copySimdCell(dpScout, activeCell, cmp, TMatrixType());
+    _updateHostPositions(dpScout, cmp, navigator, TMatrixType());
+}
+
+// ----------------------------------------------------------------------------
+// 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, typename TExecPolicy>
+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, TExecPolicy> 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, typename TExecPolicy>
+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, TExecPolicy> const &)
+{
+    using TSimdMaskVec = typename SimdMaskVector<typename TTraits::TSimdVector>::Type;
+    return createVector<TSimdMaskVec>(0);
+}
+
+// Tracking the last row is enabled
+template <typename TDPCell, typename TTraits,
+          typename TIsLastColumn,
+          typename TIsLastRow,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig, typename TExecPolicy>
+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, TExecPolicy> const &)
+{
+    using TSimdVec = typename TTraits::TSimdVector;
+    return (createVector<TSimdVec>(dpScout.state->posH) <= (dpScout.state->endPosVecH)) &
+           (createVector<TSimdVec>(dpScout.state->posV) == (dpScout.state->endPosVecV));
 }
 
 // ----------------------------------------------------------------------------
@@ -249,8 +311,8 @@ inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariab
                             DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, False, False>>,
                                        TGapModel, TTraceConfig> const &)
 {
-    using TSimdVec = typename TTraits::TSimdVector;
-    return createVector<TSimdVec>(0);
+    using TSimdMaskVec = typename SimdMaskVector<typename TTraits::TSimdVector>::Type;
+    return createVector<TSimdMaskVec>(0);
 }
 
 // Tracking the last row is enabled
@@ -278,8 +340,8 @@ inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariab
                             DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, True, False>>,
                                        TGapModel, TTraceConfig> const &)
 {
-    using TSimdVec = typename TTraits::TSimdVector;
-    return createVector<TSimdVec>(0);
+    using TSimdMaskVec = typename SimdMaskVector<typename TTraits::TSimdVector>::Type;
+    return createVector<TSimdMaskVec>(0);
 }
 
 // Tracking if the last column is enabled
@@ -307,8 +369,8 @@ inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariab
                             DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, False, True>>,
                                        TGapModel, TTraceConfig> const &)
 {
-    using TSimdVec = typename TTraits::TSimdVector;
-    return createVector<TSimdVec>(0);
+    using TSimdMaskVec = typename SimdMaskVector<typename TTraits::TSimdVector>::Type;
+    return createVector<TSimdMaskVec>(0);
 }
 
 // Tracking if the last column and last row is enabled
@@ -361,8 +423,8 @@ inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariab
                             DPProfile_<GlobalAlignment_<FreeEndGaps_<TTop, TLeft, True, True>>,
                                        TGapModel, TTraceConfig> const &)
 {
-    using TSimdVec = typename TTraits::TSimdVector;
-    return createVector<TSimdVec>(0);
+    using TSimdMaskVec = typename SimdMaskVector<typename TTraits::TSimdVector>::Type;
+    return createVector<TSimdMaskVec>(0);
 }
 
 // If local alignment.
@@ -385,6 +447,121 @@ inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariab
 // ----------------------------------------------------------------------------
 
 template <typename TDPCell, typename TTraits,
+          typename TIsLastColumn,
+          typename TTop, typename TLeft, typename TGapModel, typename TTraceConfig, typename TExecPolicy>
+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, TExecPolicy> const &)
+{
+    using TSimdMaskVec = typename SimdMaskVector<typename TTraits::TSimdVector>::Type;
+    return createVector<TSimdMaskVec>(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, typename TExecPolicy>
+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, TExecPolicy> 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, typename TExecPolicy>
+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, TExecPolicy> 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, typename TExecPolicy>
+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, TExecPolicy> 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, typename TExecPolicy>
+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, TExecPolicy> 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, typename TExecPolicy>
+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, TExecPolicy> 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, typename TExecPolicy>
+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, TExecPolicy> const &)
+{
+    using TSimdMaskVec = typename SimdMaskVector<typename TTraits::TSimdVector>::Type;
+    return createVector<TSimdMaskVec>(0);
+}
+
+// If local alignment.
+template <typename TDPCell, typename TTraits,
+          typename TIsLastColumn,
+          typename TIsLastRow,
+          typename TAlgoSpec, typename TGapModel, typename TTraceConfig, typename TExecPolicy>
+inline auto _getCompareMask(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & dpScout,
+                            TIsLastColumn const & /*lastCol*/,
+                            TIsLastRow const & /*lastRow*/,
+                            DPProfile_<LocalAlignment_<TAlgoSpec>, TGapModel, TTraceConfig, TExecPolicy> 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,
           typename TIsLastRow>
@@ -395,27 +572,56 @@ _scoutBestScore(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTr
                 TIsLastColumn const & /**/,
                 TIsLastRow const & /**/)
 {
+    using TMatrixType = typename MatrixType<TTraceMatrixNavigator>::Type;
     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)));
+    _copySimdCell(dpScout, activeCell, mask, TMatrixType());
+    _updateHostPositions(dpScout, mask, navigator, TMatrixType());
 }
 
 // ----------------------------------------------------------------------------
-// Function maxHostPosition()
+// Function maxHostCoordinate()
 // ----------------------------------------------------------------------------
 
+template <typename TDPCell, typename TScoutSpec,
+          typename TDimension>
+inline auto
+maxHostCoordinate(DPScout_<TDPCell, SimdAlignmentScout<TScoutSpec> > const & dpScout,
+                  TDimension const dimension)
+{
+    return (dimension == DPMatrixDimension_::HORIZONTAL) ? dpScout.mHorizontalPos[dpScout._simdLane] :
+            dpScout.mVerticalPos[dpScout._simdLane];
+}
+
 template <typename TDPCell, typename TScoutSpec>
-inline unsigned int
-maxHostPosition(DPScout_<TDPCell, SimdAlignmentScout<TScoutSpec> > const & dpScout)
+inline auto
+maxHostCoordinates(DPScout_<TDPCell, SimdAlignmentScout<TScoutSpec> > const & dpScout)
 {
-    if(dpScout._simdLane < LENGTH<SimdVector<int32_t>::Type>::VALUE)
-        return value(dpScout._maxHostLow, dpScout._simdLane);
-    else
-        return value(dpScout._maxHostHigh, dpScout._simdLane - LENGTH<SimdVector<int32_t>::Type>::VALUE);
+    return std::make_pair(maxHostCoordinate(dpScout, DPMatrixDimension_::HORIZONTAL),
+                          maxHostCoordinate(dpScout, DPMatrixDimension_::VERTICAL));
 }
 
 // ----------------------------------------------------------------------------
+// Function maxScoreAt()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TScoutSpec>
+inline auto
+maxScoreAt(DPScout_<TDPCell, SimdAlignmentScout<TScoutSpec> > const & dpScout)
+{
+    return maxScore(dpScout)[dpScout._simdLane];
+}
+
+// ----------------------------------------------------------------------------
+// Function maxHostPosition()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TScoutSpec>
+[[deprecated("Use maxHostCoordinate instead!")]] auto
+maxHostPosition(DPScout_<TDPCell, SimdAlignmentScout<TScoutSpec> > const & /*unused*/)
+{}
+
+// ----------------------------------------------------------------------------
 // Function _setSimdLane()
 // ----------------------------------------------------------------------------
 
@@ -536,7 +742,8 @@ inline auto
 _hostLengthH(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & scout,
              TSeqH const & /*seqH*/)
 {
-    return (scout.state->endPosVecH)[scout._simdLane];
+    using TInnerValue = typename Value<typename TTraits::TSimdVector>::Type;
+    return static_cast<TInnerValue>(scout.state->endPosVecH[scout._simdLane]);
 }
 
 // ----------------------------------------------------------------------------
@@ -556,7 +763,8 @@ inline auto
 _hostLengthV(DPScout_<TDPCell, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > const & scout,
              TSeqV const & /*seqV*/)
 {
-    return (scout.state->endPosVecV)[scout._simdLane];
+    using TInnerValue = typename Value<typename TTraits::TSimdVector>::Type;
+    return static_cast<TInnerValue>(scout.state->endPosVecV[scout._simdLane]);
 }
 
 }  // namespace seqan
diff --git a/include/seqan/align/dp_setup.h b/include/seqan/align/dp_setup.h
index 29bf429..96f04e3 100644
--- a/include/seqan/align/dp_setup.h
+++ b/include/seqan/align/dp_setup.h
@@ -215,21 +215,21 @@ struct SetupAlignmentProfile_;
 template <typename TFreeEndGaps, typename TGapCosts, typename TTraceSwitch>
 struct SetupAlignmentProfile_<DPGlobal, TFreeEndGaps, TGapCosts, TTraceSwitch>
 {
-    typedef DPProfile_<GlobalAlignment_<TFreeEndGaps>, TGapCosts, TTraceSwitch> Type;
+    typedef DPProfile_<GlobalAlignment_<TFreeEndGaps>, TGapCosts, TTraceSwitch, Serial> Type;
 };
 
 // Profile for Smith-Waterman algorithm.
 template <typename TFreeEndGaps, typename TGapCosts, typename TTraceSwitch>
 struct SetupAlignmentProfile_<DPLocal, TFreeEndGaps, TGapCosts, TTraceSwitch>
 {
-    typedef DPProfile_<LocalAlignment_<>, TGapCosts, TTraceSwitch> Type;
+    typedef DPProfile_<LocalAlignment_<>, TGapCosts, TTraceSwitch, Serial> Type;
 };
 
 // Profile for Waterman-Eggert algorithm
 template <typename TFreeEndGaps, typename TGapCosts, typename TTraceSwitch>
 struct SetupAlignmentProfile_<DPLocalEnumerate, TFreeEndGaps, TGapCosts, TTraceSwitch>
 {
-    typedef DPProfile_<LocalAlignment_<SuboptimalAlignment>, TGapCosts, TracebackOn<TracebackConfig_<SingleTrace, GapsLeft> > > Type;
+    typedef DPProfile_<LocalAlignment_<SuboptimalAlignment>, TGapCosts, TracebackOn<TracebackConfig_<SingleTrace, GapsLeft> >, Serial> Type;
 };
 
 
@@ -263,16 +263,17 @@ _usesAffineGaps(TScoringScheme const & scoringScheme,
 // Function _setUpAndRunAlignment()
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TGapModel,
+// Scalar implementation.
+template <typename TScoreValue, typename TGapSpec, typename TTraceValue, typename TScoreMat, typename TTraceMat,
+          typename TTraceSegment, typename TSpec,
           typename TDPScoutStateSpec,
-          typename TTrace,
           typename TSequenceH,
           typename TSequenceV,
           typename TScoreValue2, typename TScoreSpec,
           typename TDPType, typename TBand, typename TFreeEndGaps, typename TTraceConfig>
 typename Value<Score<TScoreValue2, TScoreSpec> >::Type
-_setUpAndRunAlignment(DPContext<TScoreValue, TGapModel> & dpContext,
-                      TTrace & traceSegments,
+_setUpAndRunAlignment(DPContext<DPCell_<TScoreValue, TGapSpec>, TTraceValue, TScoreMat, TTraceMat> & dpContext,
+                      String<TTraceSegment, TSpec> & traceSegments,
                       DPScoutState_<TDPScoutStateSpec> & dpScoutState,
                       TSequenceH const & seqH,
                       TSequenceV const & seqV,
@@ -282,12 +283,12 @@ _setUpAndRunAlignment(DPContext<TScoreValue, TGapModel> & dpContext,
     SEQAN_ASSERT_GEQ(length(seqH), 1u);
     SEQAN_ASSERT_GEQ(length(seqV), 1u);
 
-    typedef typename SetupAlignmentProfile_<TDPType, TFreeEndGaps, TGapModel, TTraceConfig>::Type TDPProfile;
+    typedef typename SetupAlignmentProfile_<TDPType, TFreeEndGaps, TGapSpec, TTraceConfig>::Type TDPProfile;
     return _computeAlignment(dpContext, traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig._band,
                              TDPProfile());
 }
 
-template <typename TTrace,
+template <typename TTraceSegment, typename TSpec,
           typename TDPScoutStateSpec,
           typename TSequenceH,
           typename TSequenceV,
@@ -295,7 +296,65 @@ template <typename TTrace,
           typename TDPType, typename TBand, typename TFreeEndGaps, typename TTraceConfig,
           typename TGapModel>
 typename Value<Score<TScoreValue2, TScoreSpec> >::Type
-_setUpAndRunAlignment(TTrace & traceSegments,
+_setUpAndRunAlignment(String<TTraceSegment, TSpec> & traceSegments,
+                      DPScoutState_<TDPScoutStateSpec> & dpScoutState,
+                      TSequenceH const & seqH,
+                      TSequenceV const & seqV,
+                      Score<TScoreValue2, TScoreSpec> const & scoringScheme,
+                      AlignConfig2<TDPType, TBand, TFreeEndGaps, TTraceConfig> const & alignConfig,
+                      TGapModel const & /**/)
+{
+    DPContext<DPCell_<TScoreValue2, TGapModel>, typename TraceBitMap_<>::Type> dpContext;
+    return _setUpAndRunAlignment(dpContext, traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig);
+}
+
+template <typename TTraceSegment, typename TSpec, typename TDPScoutStateSpec,
+          typename TSequenceH, typename TSequenceV, typename TScoreValue2, typename TScoreSpec, typename TDPType,
+          typename TBand, typename TFreeEndGaps, typename TTraceConfig>
+typename Value<Score<TScoreValue2, TScoreSpec> >::Type
+_setUpAndRunAlignment(String<TTraceSegment, TSpec> & traceSegments,
+                      DPScoutState_<TDPScoutStateSpec> & dpScoutState,
+                      TSequenceH const & seqH,
+                      TSequenceV const & seqV,
+                      Score<TScoreValue2, TScoreSpec> const & scoringScheme,
+                      AlignConfig2<TDPType, TBand, TFreeEndGaps, TTraceConfig> const & alignConfig)
+{
+    if (_usesAffineGaps(scoringScheme, seqH, seqV))
+        return _setUpAndRunAlignment(traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig, AffineGaps());
+    else
+        return _setUpAndRunAlignment(traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig, LinearGaps());
+}
+
+// SIMD aware implementation.
+template <typename TScoreValue, typename TGapSpec, typename TTraceValue, typename TScoreMat, typename TTraceMat,
+          typename TTraceSegment, typename TSpec,
+          typename TDPScoutStateSpec,
+          typename TSequenceH,
+          typename TSequenceV,
+          typename TScoreValue2, typename TScoreSpec,
+          typename TDPType, typename TBand, typename TFreeEndGaps, typename TTraceConfig>
+typename Value<Score<TScoreValue2, TScoreSpec> >::Type
+_setUpAndRunAlignment(DPContext<DPCell_<TScoreValue, TGapSpec>, TTraceValue, TScoreMat, TTraceMat> & dpContext,
+                      StringSet<String<TTraceSegment, TSpec> > & traceSegments,
+                      DPScoutState_<TDPScoutStateSpec> & dpScoutState,
+                      TSequenceH const & seqH,
+                      TSequenceV const & seqV,
+                      Score<TScoreValue2, TScoreSpec> const & scoringScheme,
+                      AlignConfig2<TDPType, TBand, TFreeEndGaps, TTraceConfig> const & alignConfig)
+{
+    SEQAN_ASSERT_GEQ(length(seqH), 1u);
+    SEQAN_ASSERT_GEQ(length(seqV), 1u);
+
+    typedef typename SetupAlignmentProfile_<TDPType, TFreeEndGaps, TGapSpec, TTraceConfig>::Type TDPProfile;
+    return _computeAlignment(dpContext, traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig._band,
+                             TDPProfile());
+}
+
+template <typename TTraceSegment, typename TSpec, typename TDPScoutStateSpec,
+          typename TSequenceH, typename TSequenceV, typename TScoreValue2, typename TScoreSpec, typename TDPType,
+          typename TBand, typename TFreeEndGaps, typename TTraceConfig, typename TGapModel>
+typename Value<Score<TScoreValue2, TScoreSpec> >::Type
+_setUpAndRunAlignment(StringSet<String<TTraceSegment, TSpec> > & traceSegments,
                       DPScoutState_<TDPScoutStateSpec> & dpScoutState,
                       TSequenceH const & seqH,
                       TSequenceV const & seqV,
@@ -303,7 +362,12 @@ _setUpAndRunAlignment(TTrace & traceSegments,
                       AlignConfig2<TDPType, TBand, TFreeEndGaps, TTraceConfig> const & alignConfig,
                       TGapModel const & /**/)
 {
-    DPContext<TScoreValue2, TGapModel> dpContext;
+    typedef DPCell_<TScoreValue2, TGapModel> TDPCell;
+    typedef typename TraceBitMap_<TScoreValue2>::Type TTraceValue;
+    typedef String<TDPCell, Alloc<OverAligned> > TScoreHost;
+    typedef String<TTraceValue, Alloc<OverAligned> > TTraceHost;
+
+    DPContext<TDPCell, TTraceValue, TScoreHost, TTraceHost> dpContext;
     return _setUpAndRunAlignment(dpContext, traceSegments, dpScoutState, seqH, seqV, scoringScheme, alignConfig);
 }
 
diff --git a/include/seqan/align/dp_trace_segment.h b/include/seqan/align/dp_trace_segment.h
index 2b591be..deb1765 100644
--- a/include/seqan/align/dp_trace_segment.h
+++ b/include/seqan/align/dp_trace_segment.h
@@ -69,7 +69,7 @@ public:
     TTraceValue _traceValue;            // the trace direction
 
     TraceSegment_() :
-        _horizontalBeginPos(0), _verticalBeginPos(0), _length(0), _traceValue(+TraceBitMap_<TTraceValue>::NONE){}
+        _horizontalBeginPos(0), _verticalBeginPos(0), _length(0), _traceValue(TraceBitMap_<TTraceValue>::NONE){}
 
     TraceSegment_(TraceSegment_ const & other) :
         _horizontalBeginPos(other._horizontalBeginPos),
@@ -328,11 +328,11 @@ inline void _recordSegment(TTraceSegments & traceSegments,
         return;  // we don't store empty segments
 
     if (traceValue & TraceBitMap_<TTraceValue>::DIAGONAL)
-        appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, +TraceBitMap_<TTraceValue>::DIAGONAL));
+        appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, TraceBitMap_<TTraceValue>::DIAGONAL));
     else if (traceValue & TraceBitMap_<TTraceValue>::VERTICAL)
-        appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, +TraceBitMap_<TTraceValue>::VERTICAL));
+        appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, TraceBitMap_<TTraceValue>::VERTICAL));
     else if (traceValue & TraceBitMap_<TTraceValue>::HORIZONTAL)
-        appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, +TraceBitMap_<TTraceValue>::HORIZONTAL));
+        appendValue(traceSegments, TTraceSegment(horizontalBeginPos, verticalBeginPos, segmentLength, TraceBitMap_<TTraceValue>::HORIZONTAL));
     // everything else is not tracked.
 }
 
diff --git a/include/seqan/align/dp_traceback_impl.h b/include/seqan/align/dp_traceback_impl.h
index 0e7cc72..31db158 100644
--- a/include/seqan/align/dp_traceback_impl.h
+++ b/include/seqan/align/dp_traceback_impl.h
@@ -115,12 +115,11 @@ public:
 template <typename TDPProfile>
 struct PreferGapsAtEnd_ : False{};
 
-template <typename TAlgorithm, typename TTracebackSpec>
-struct PreferGapsAtEnd_<DPProfile_<TAlgorithm, AffineGaps, TTracebackSpec > > : True{};
-
-template <typename TAlgorithm, typename TTraceSpec>
-struct PreferGapsAtEnd_<DPProfile_<TAlgorithm, LinearGaps, TracebackOn<TracebackConfig_<TTraceSpec, GapsRight> > > > : True{};
+template <typename TAlgorithm, typename TTracebackSpec, typename TExecSpec>
+struct PreferGapsAtEnd_<DPProfile_<TAlgorithm, AffineGaps, TTracebackSpec, TExecSpec> > : True{};
 
+template <typename TAlgorithm, typename TTraceSpec, typename TExecSpec>
+struct PreferGapsAtEnd_<DPProfile_<TAlgorithm, LinearGaps, TracebackOn<TracebackConfig_<TTraceSpec, GapsRight> >, TExecSpec> > : True{};
 
 // ============================================================================
 // Functions
@@ -143,13 +142,13 @@ _hasReachedEnd(TracebackCoordinator_<TPosition> const & coordinator)
 
 template <typename TPosition, typename TBandFlag, typename TSizeH, typename TSizeV>
 inline void
-_initTracebackCoordinator(TracebackCoordinator_<TPosition> & coordinator,
-                          DPBandConfig<TBandFlag> const & band,
-                          TSizeH seqHSize,
-                          TSizeV seqVSize)
+_initTracebackCoordinator(SEQAN_UNUSED TracebackCoordinator_<TPosition> & coordinator,
+                          SEQAN_UNUSED DPBandConfig<TBandFlag> const & band,
+                          SEQAN_UNUSED TSizeH seqHSize,
+                          SEQAN_UNUSED TSizeV seqVSize)
 {
     typedef typename Position<DPBandConfig<TBandFlag> >::Type TBandPosition;
-    if (IsSameType<TBandFlag, BandOn>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TBandFlag, BandOn>::VALUE)
     {
         // Adapt the current column value when the lower diagonal is positive (shift right in horizontal direction).
         if (lowerDiagonal(band) >= 0)
@@ -184,7 +183,6 @@ _isInBand(TracebackCoordinator_<TPosition> const & coordinator)
     return (coordinator._currColumn > coordinator._breakpoint1 || coordinator._currColumn <= coordinator._breakpoint2);
 }
 
-
 // ----------------------------------------------------------------------------
 // Function _doTracebackGoDiagonal()
 // ----------------------------------------------------------------------------
@@ -239,9 +237,10 @@ _doTracebackGoVertical(TTarget & target,
         fragmentLength = 0;
     }
     // We are in a vertical gap. So continue after we reach the end of the vertical gap.
-    if (IsSameType<TGapCosts, AffineGaps>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TGapCosts, AffineGaps>::VALUE)
     {
-        while ((!(traceValue & TraceBitMap_<>::VERTICAL_OPEN) || (traceValue & TraceBitMap_<>::VERTICAL)) && (tracebackCoordinator._currRow != 1))
+        while ((!(traceValue & TraceBitMap_<>::VERTICAL_OPEN) || (traceValue & TraceBitMap_<>::VERTICAL)) &&
+               tracebackCoordinator._currRow != 1)
         {
             _traceVertical(matrixNavigator, _isInBand(tracebackCoordinator));
             traceValue = scalarValue(matrixNavigator);
@@ -316,9 +315,10 @@ _doTracebackGoHorizontal(TTarget & target,
         lastTraceValue = TraceBitMap_<>::HORIZONTAL;
         fragmentLength = 0;
     }
-    if (IsSameType<TGapCosts, AffineGaps>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TGapCosts, AffineGaps>::VALUE)
     {
-        while ((!(traceValue & TraceBitMap_<>::HORIZONTAL_OPEN) || (traceValue & TraceBitMap_<>::HORIZONTAL)) && (tracebackCoordinator._currColumn != 1))
+        while ((!(traceValue & TraceBitMap_<>::HORIZONTAL_OPEN) || (traceValue & TraceBitMap_<>::HORIZONTAL)) &&
+               tracebackCoordinator._currColumn != 1)
         {
             _traceHorizontal(matrixNavigator, _isInBand(tracebackCoordinator));
             traceValue = scalarValue(matrixNavigator);
@@ -487,52 +487,46 @@ _retrieveInitialTraceDirection(TTraceValue & traceValue, TDPProfile const & /*dp
 // ----------------------------------------------------------------------------
 
 template <typename TTarget,
+          typename TTraceValue,
           typename TDPTraceMatrixNavigator,
           typename TSizeH,
           typename TSizeV,
           typename TBandFlag,
-          typename TAlgorithm, typename TGapCosts, typename TTracebackSpec>
-inline SEQAN_FUNC_DISABLE_IF(Is<ContainerConcept<TSizeH> >, void)
-_computeTraceback(TTarget & target,
-                  TDPTraceMatrixNavigator & matrixNavigator,
-                  unsigned  maxHostPosition,
-                  TSizeH const & seqHSize,
-                  TSizeV const & seqVSize,
-                  DPBandConfig<TBandFlag> const & band,
-                  DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec> const & dpProfile)
+          typename TAlgorithm, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy,
+          typename TTraceHead,
+          typename TTraceTail>
+void _computeTraceback(TTarget & target,
+                       TTraceValue & traceValue,
+                       TTraceValue & lastTraceValue,
+                       TDPTraceMatrixNavigator & matrixNavigator,
+                       TSizeH const & seqHSize,
+                       TSizeV const & seqVSize,
+                       DPBandConfig<TBandFlag> const & band,
+                       DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec, TExecPolicy> const & /*dpProfile*/,
+                       TTraceHead const &,
+                       TTraceTail const &)
 {
-    typedef typename Container<TDPTraceMatrixNavigator>::Type TContainer;
-    typedef typename Size<TContainer>::Type TSize;
-    typedef typename Position<TContainer>::Type TPosition;
-    typedef typename TraceBitMap_<>::Type TTraceValue;
+    typedef typename Size<TTarget>::Type TSize;
+    typedef typename Position<TDPTraceMatrixNavigator>::Type TPosition;
 
-    if (IsSameType<TTracebackSpec, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTracebackSpec, TracebackOff>::VALUE)
         return;
 
     // Determine whether or not we place gaps to the left.
     typedef typename IsGapsLeft_<TTracebackSpec>::Type TIsGapsLeft;
 
-    // Set the navigator to the position where the maximum was found.
-    _setToPosition(matrixNavigator, maxHostPosition);
-
-    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);
-
     TracebackCoordinator_<TPosition> tracebackCoordinator(coordinate(matrixNavigator, +DPMatrixDimension_::HORIZONTAL),
                                                           coordinate(matrixNavigator, +DPMatrixDimension_::VERTICAL),
                                                           band, seqHSize, seqVSize);
 
-    if (TraceTail_<TAlgorithm>::VALUE)
+    if (TTraceTail::VALUE)
     {
         if (tracebackCoordinator._currRow != static_cast<TSize>(seqVSize))
             _recordSegment(target, seqHSize, tracebackCoordinator._currRow, seqVSize - tracebackCoordinator._currRow,
-                           +TraceBitMap_<>::VERTICAL);
+                           TraceBitMap_<>::VERTICAL);
         if (tracebackCoordinator._currColumn != static_cast<TSize>(seqHSize))
             _recordSegment(target, tracebackCoordinator._currColumn, tracebackCoordinator._currRow, seqHSize -
-                           tracebackCoordinator._currColumn, +TraceBitMap_<>::HORIZONTAL);
+                           tracebackCoordinator._currColumn, TraceBitMap_<>::HORIZONTAL);
     }
 
     TSize fragmentLength = 0;
@@ -541,59 +535,92 @@ _computeTraceback(TTarget & target,
 
     // Record last detected fragment.
     _recordSegment(target, tracebackCoordinator._currColumn, tracebackCoordinator._currRow, fragmentLength, lastTraceValue);
-    if (TraceHead_<TAlgorithm>::VALUE)
+    if (TTraceHead::VALUE)
     {
         // Record leading gaps if any.
         if (tracebackCoordinator._currRow != 0u)
-            _recordSegment(target, 0, 0, tracebackCoordinator._currRow, +TraceBitMap_<>::VERTICAL);
+            _recordSegment(target, 0, 0, tracebackCoordinator._currRow, TraceBitMap_<>::VERTICAL);
         if (tracebackCoordinator._currColumn != 0u)
-            _recordSegment(target, 0, 0, tracebackCoordinator._currColumn, +TraceBitMap_<>::HORIZONTAL);
+            _recordSegment(target, 0, 0, tracebackCoordinator._currColumn, TraceBitMap_<>::HORIZONTAL);
     }
 }
 
-//// Needed as a delegation method to allow invocation of both methods with host position and dpScout.
+// Needed as a delegation method to allow invocation of both methods with host position and dpScout.
+// With sizes and maxHostPosition.
 template <typename TTarget,
           typename TDPTraceMatrixNavigator,
-          typename TSequenceH,
-          typename TSequenceV,
+          typename TSeqHSize,
+          typename TSeqVSize,
           typename TBandFlag,
-          typename TAlgorithm, typename TGapCosts, typename TTracebackSpec>
-inline SEQAN_FUNC_ENABLE_IF(Is<ContainerConcept<TSequenceH> >, void)
+          typename TAlgorithm, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy>
+inline SEQAN_FUNC_DISABLE_IF(Is<ContainerConcept<TSeqHSize> >, void)
 _computeTraceback(TTarget & target,
                   TDPTraceMatrixNavigator & matrixNavigator,
                   unsigned  maxHostPosition,
-                  TSequenceH const & seqH,
-                  TSequenceV const & seqV,
+                  TSeqHSize const & seqHSize,
+                  TSeqVSize const & seqVSize,
                   DPBandConfig<TBandFlag> const & band,
-                  DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec> const & dpProfile)
+                  DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec, TExecPolicy> const & dpProfile)
 {
-    _computeTraceback(target, matrixNavigator, maxHostPosition, length(seqH), length(seqV), band, dpProfile);
+    using TSize SEQAN_TYPEDEF_FOR_DEBUG = typename Size<TTarget>::Type;
+    // Set the navigator to the position where the maximum was found.
+    _setToPosition(matrixNavigator, maxHostPosition);
+
+    SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::HORIZONTAL), static_cast<TSize>(seqHSize));
+    SEQAN_ASSERT_LEQ(coordinate(matrixNavigator, +DPMatrixDimension_::VERTICAL), static_cast<TSize>(seqVSize));
+    typename TraceBitMap_<>::Type traceValue = scalarValue(matrixNavigator);
+    typename TraceBitMap_<>::Type lastTraceValue = _retrieveInitialTraceDirection(traceValue, dpProfile);
+    _computeTraceback(target, traceValue, lastTraceValue, matrixNavigator, seqHSize, seqVSize, band, dpProfile,
+                      TraceHead_<TAlgorithm>(), TraceTail_<TAlgorithm>());
 }
 
+// With sizes and dpScout.
 template <typename TTarget,
           typename TDPTraceMatrixNavigator,
           typename TDPCell, typename TScoutSpec,
-          typename TSizeH,
-          typename TSizeV,
+          typename TSeqHSize,
+          typename TSeqVSize,
           typename TBandFlag,
-          typename TAlgorithm,
-          typename TGapCosts,
-          typename TTracebackSpec>
-inline SEQAN_FUNC_DISABLE_IF(Is<ContainerConcept<TSizeH> >, void)
+          typename TAlgorithm, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy>
+inline SEQAN_FUNC_DISABLE_IF(Is<ContainerConcept<TSeqHSize> >, void)
 _computeTraceback(TTarget & target,
                   TDPTraceMatrixNavigator & matrixNavigator,
                   DPScout_<TDPCell, TScoutSpec> const & dpScout,
-                  TSizeH const & seqHSize,
-                  TSizeV const & seqVSize,
+                  TSeqHSize const & seqHSize,
+                  TSeqVSize const & seqVSize,
                   DPBandConfig<TBandFlag> const & band,
-                  DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec> const & dpProfile)
+                  DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec, TExecPolicy> const & dpProfile)
 {
     _computeTraceback(target, matrixNavigator, maxHostPosition(dpScout), seqHSize, seqVSize, band, dpProfile);
 }
 
-template <typename TTarget, typename TDPTraceMatrixNavigator, typename TDPCell, typename TScoutSpec,
-          typename TSequenceH, typename TSequenceV, typename TBandFlag, typename TAlgorithm, typename TGapCosts,
-          typename TTracebackSpec>
+// With sequences and maxHostPosition.
+template <typename TTarget,
+          typename TDPTraceMatrixNavigator,
+          typename TSequenceH,
+          typename TSequenceV,
+          typename TBandFlag,
+          typename TAlgorithm, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy>
+inline SEQAN_FUNC_ENABLE_IF(Is<ContainerConcept<TSequenceH> >, void)
+_computeTraceback(TTarget & target,
+                  TDPTraceMatrixNavigator & matrixNavigator,
+                  unsigned  maxHostPosition,
+                  TSequenceH const & seqH,
+                  TSequenceV const & seqV,
+                  DPBandConfig<TBandFlag> const & band,
+                  DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec, TExecPolicy> const & dpProfile)
+{
+    _computeTraceback(target, matrixNavigator, maxHostPosition, length(seqH), length(seqV), band, dpProfile);
+}
+
+// With sequences and dpScout.
+template <typename TTarget,
+          typename TDPTraceMatrixNavigator,
+          typename TDPCell, typename TScoutSpec,
+          typename TSequenceH,
+          typename TSequenceV,
+          typename TBandFlag,
+          typename TAlgorithm, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy>
 inline SEQAN_FUNC_ENABLE_IF(Is<ContainerConcept<TSequenceH> >, void)
 _computeTraceback(TTarget & target,
                   TDPTraceMatrixNavigator & matrixNavigator,
@@ -601,9 +628,9 @@ _computeTraceback(TTarget & target,
                   TSequenceH const & seqH,
                   TSequenceV const & seqV,
                   DPBandConfig<TBandFlag> const & band,
-                  DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec> const & dpProfile)
+                  DPProfile_<TAlgorithm, TGapCosts, TTracebackSpec, TExecPolicy> const & dpProfile)
 {
-    _computeTraceback(target, matrixNavigator, maxHostPosition(dpScout), length(seqH), length(seqV), band, dpProfile);
+    _computeTraceback(target, matrixNavigator, maxHostPosition(dpScout), seqH, seqV, band, dpProfile);
 }
 
 }  // namespace seqan
diff --git a/include/seqan/align/gaps_anchor.h b/include/seqan/align/gaps_anchor.h
index 154f1c6..3ee0dc3 100644
--- a/include/seqan/align/gaps_anchor.h
+++ b/include/seqan/align/gaps_anchor.h
@@ -301,7 +301,7 @@ template <typename TSize, typename TSource, typename TGapAnchors>
 inline void
 _assignSourceLength(TSize & size, Gaps<TSource, AnchorGaps<TGapAnchors> > const & me)
 {
-    if (IsSameType<TSource, Nothing>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TSource, Nothing>::VALUE)
         size = std::numeric_limits<TSize>::max() / 2;
     else
         size = length(value(me.data_source));
diff --git a/include/seqan/align/gaps_base.h b/include/seqan/align/gaps_base.h
index ed29a01..6c4ad8d 100644
--- a/include/seqan/align/gaps_base.h
+++ b/include/seqan/align/gaps_base.h
@@ -143,6 +143,12 @@ typedef Tag<RightOfViewPos_> RightOfViewPos;
 template <typename TSequence, typename TSpec = ArrayGaps>
 class Gaps;
 
+template <typename TSequence, typename TSpec>
+SEQAN_CONCEPT_IMPL((Gaps<TSequence, TSpec>), (AlignedSequenceConcept));
+
+template <typename TSequence, typename TSpec>
+SEQAN_CONCEPT_IMPL((Gaps<TSequence, TSpec> const), (AlignedSequenceConcept));
+
 // ============================================================================
 // Metafunctions
 // ============================================================================
diff --git a/include/seqan/align/global_alignment_banded.h b/include/seqan/align/global_alignment_banded.h
index eab33c6..bacaf81 100644
--- a/include/seqan/align/global_alignment_banded.h
+++ b/include/seqan/align/global_alignment_banded.h
@@ -399,13 +399,17 @@ template <typename TSequenceH,
           typename TScoreValue, typename TScoreSpec,
           bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec,
           typename TAlgoTag>
-TScoreValue globalAlignmentScore(TSequenceH const & seqH,
-                                 TSequenceV const & seqV,
-                                 Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                 AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & /*alignConfig*/,
-                                 int lowerDiag,
-                                 int upperDiag,
-                                 TAlgoTag const & /*algoTag*/)
+SEQAN_FUNC_DISABLE_IF(And<And<Is<ContainerConcept<TSequenceH>>, Is<ContainerConcept<typename Value<TSequenceH>::Type>>>,
+                          And<Is<ContainerConcept<TSequenceV>>, Is<ContainerConcept<typename Value<TSequenceH>::Type>>>
+                         >,
+                      TScoreValue)
+globalAlignmentScore(TSequenceH const & seqH,
+                     TSequenceV const & seqV,
+                     Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                     AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & /*alignConfig*/,
+                     int lowerDiag,
+                     int upperDiag,
+                     TAlgoTag const & /*algoTag*/)
 {
     typedef AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> TAlignConfig;
     typedef typename SubstituteAlignConfig_<TAlignConfig>::Type TFreeEndGaps;
@@ -423,12 +427,12 @@ template <typename TSequenceH,
           typename TSequenceV,
           typename TScoreValue, typename TScoreSpec,
           typename TAlgoTag>
-TScoreValue globalAlignmentScore(TSequenceH const & seqH,
-                                 TSequenceV const & seqV,
-                                 Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                 int lowerDiag,
-                                 int upperDiag,
-                                 TAlgoTag const & algoTag)
+auto globalAlignmentScore(TSequenceH const & seqH,
+                          TSequenceV const & seqV,
+                          Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                          int lowerDiag,
+                          int upperDiag,
+                          TAlgoTag const & algoTag)
 {
     AlignConfig<> alignConfig;
     return globalAlignmentScore(seqH, seqV, scoringScheme, alignConfig, lowerDiag, upperDiag, algoTag);
@@ -439,12 +443,12 @@ template <typename TSequenceH,
           typename TSequenceV,
           typename TScoreValue, typename TScoreSpec,
           bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec>
-TScoreValue globalAlignmentScore(TSequenceH const & seqH,
-                                 TSequenceV const & seqV,
-                                 Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                 AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & alignConfig,
-                                 int lowerDiag,
-                                 int upperDiag)
+auto globalAlignmentScore(TSequenceH const & seqH,
+                          TSequenceV const & seqV,
+                          Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                          AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & alignConfig,
+                          int lowerDiag,
+                          int upperDiag)
 {
     if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme))
         return globalAlignmentScore(seqH, seqV, scoringScheme, alignConfig, lowerDiag, upperDiag, NeedlemanWunsch());
@@ -456,11 +460,11 @@ TScoreValue globalAlignmentScore(TSequenceH const & seqH,
 template <typename TSequenceH,
           typename TSequenceV,
           typename TScoreValue, typename TScoreSpec>
-TScoreValue globalAlignmentScore(TSequenceH const & seqH,
-                                 TSequenceV const & seqV,
-                                 Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                 int lowerDiag,
-                                 int upperDiag)
+auto globalAlignmentScore(TSequenceH const & seqH,
+                          TSequenceV const & seqV,
+                          Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                          int lowerDiag,
+                          int upperDiag)
 {
     AlignConfig<> alignConfig;
     return globalAlignmentScore(seqH, seqV, scoringScheme, alignConfig, lowerDiag, upperDiag);
@@ -551,17 +555,22 @@ TScoreValue globalAlignmentScore(StringSet<TString, TSpec> const & strings,
 // Function globalAlignmentScore()         [banded, SIMD version, 2x StringSet]
 // ----------------------------------------------------------------------------
 
-template <typename TString, typename TSpec,
+template <typename TSeqH,
+          typename TSeqV,
           typename TScoreValue, typename TScoreSpec,
           bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec,
           typename TAlgoTag>
-String<TScoreValue> globalAlignmentScore(StringSet<TString, TSpec> const & stringsH,
-                                         StringSet<TString, TSpec> const & stringsV,
-                                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                         AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & /*alignConfig*/,
-                                         int lowerDiag,
-                                         int upperDiag,
-                                         TAlgoTag const & /*algoTag*/)
+SEQAN_FUNC_ENABLE_IF(And<And<Is<ContainerConcept<TSeqH>>, Is<ContainerConcept<typename Value<TSeqH>::Type>>>,
+                         And<Is<ContainerConcept<TSeqV>>, Is<ContainerConcept<typename Value<TSeqV>::Type>>>
+                        >,
+                     String<TScoreValue>)
+globalAlignmentScore(TSeqH const & stringsH,
+                     TSeqV const & stringsV,
+                     Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                     AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & /*alignConfig*/,
+                     int lowerDiag,
+                     int upperDiag,
+                     TAlgoTag const & /*algoTag*/)
 {
     typedef AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> TAlignConfig;
     typedef typename SubstituteAlignConfig_<TAlignConfig>::Type TFreeEndGaps;
@@ -572,51 +581,6 @@ String<TScoreValue> globalAlignmentScore(StringSet<TString, TSpec> const & strin
     return _alignWrapper(stringsH, stringsV, scoringScheme, TAlignConfig2(lowerDiag, upperDiag), TGapModel());
 }
 
-// Interface without AlignConfig<>.
-template <typename TString, typename TSpec,
-          typename TScoreValue, typename TScoreSpec,
-          typename TAlgoTag>
-String<TScoreValue> globalAlignmentScore(StringSet<TString, TSpec> const & stringsH,
-                                         StringSet<TString, TSpec> const & stringsV,
-                                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                         int lowerDiag,
-                                         int upperDiag,
-                                         TAlgoTag const & algoTag)
-{
-    AlignConfig<> alignConfig;
-    return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, lowerDiag, upperDiag, algoTag);
-}
-
-// Interface without algorithm tag.
-template <typename TString, typename TSpec,
-          typename TScoreValue, typename TScoreSpec,
-          bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec>
-String<TScoreValue> globalAlignmentScore(StringSet<TString, TSpec> const & stringsH,
-                                         StringSet<TString, TSpec> const & stringsV,
-                                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                         AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & alignConfig,
-                                         int lowerDiag,
-                                         int upperDiag)
-{
-    if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme))
-        return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, lowerDiag, upperDiag, NeedlemanWunsch());
-    else
-        return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, lowerDiag, upperDiag, Gotoh());
-}
-
-// Interface without AlignConfig<> and algorithm tag.
-template <typename TString, typename TSpec,
-          typename TScoreValue, typename TScoreSpec>
-String<TScoreValue> globalAlignmentScore(StringSet<TString, TSpec> const & stringsH,
-                                         StringSet<TString, TSpec> const & stringsV,
-                                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                         int lowerDiag,
-                                         int upperDiag)
-{
-    AlignConfig<> alignConfig;
-    return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, lowerDiag, upperDiag);
-}
-
 // ----------------------------------------------------------------------------
 // Function globalAlignmentScore()   [banded, SIMD version, String vs StringSet]
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/align/global_alignment_unbanded.h b/include/seqan/align/global_alignment_unbanded.h
index a58c539..4f7af58 100644
--- a/include/seqan/align/global_alignment_unbanded.h
+++ b/include/seqan/align/global_alignment_unbanded.h
@@ -457,13 +457,14 @@ TScoreValue globalAlignment(String<Fragment<TSize, TFragmentSpec>, TStringSpec>
  * @headerfile <seqan/align.h>
  * @brief Computes the best global pairwise alignment score.
  *
- * @signature TScoreVal globalAlignmentScore(seqH, seqV, scoringScheme[, alignConfig][, lowerDiag, upperDiag][, algorithmTag]);
+ * @signature TScoreVal globalAlignmentScore([exec,] subject, query, scoringScheme[, alignConfig][, lowerDiag, upperDiag]);
  * @signature TScoreVal globalAlignmentScore(strings,    scoringScheme[, alignConfig][, lowerDiag, upperDiag][, algorithmTag]);
  * @signature TScoreVal globalAlignmentScore(seqH, seqV, {MyersBitVector | MyersHirschberg});
  * @signature TScoreVal globalAlignmentScore(strings,    {MyersBitVector | MyersHirschberg});
  *
- * @param[in] seqH          Horizontal gapped sequence in alignment matrix.  Types: String
- * @param[in] seqV          Vertical gapped sequence in alignment matrix.  Types: String
+ * @param[in] exec          @link ExecutionPolicy Policy at endlink to select execution mode of alignment algorithm.
+ * @param[in] subject       Subject sequence(s) (horizontal in alignment matrix). Must satisfy @link ContainerConcept @endlink or container-of-container concept.
+ * @param[in] query         Query sequence(s) (vertical in alignment matrix). Must satisfy @link ContainerConcept @endlink or container-of-container concept.
  * @param[in] strings       A @link StringSet @endlink containing two sequences.  Type: StringSet.
  * @param[in] alignConfig   The @link AlignConfig @endlink to use for the alignment.  Type: AlignConfig
  * @param[in] scoringScheme The scoring scheme to use for the alignment.  Note that the user is responsible for ensuring
@@ -474,17 +475,36 @@ TScoreValue globalAlignment(String<Fragment<TSize, TFragmentSpec>, TStringSpec>
  *                          @endlink.
  *
  * @return TScoreVal   Score value of the resulting alignment  (Metafunction: @link Score#Value @endlink of
- *                     the type of <tt>scoringScheme</tt>).
+ *                     the type of <tt>scoringScheme</tt>). If subject and query are sets the function returns a
+ *                     set of scores representing the score for each pairwise alignment (<tt>subject[i]</tt> with <tt>query[i]</tt>).
  *
  * This function does not perform the (linear time) traceback step after the (mostly quadratic time) dynamic programming
  * step.  Note that Myers' bit-vector algorithm does not compute an alignment (only in the Myers-Hirschberg variant) but
  * scores can be computed using <tt>globalAlignmentScore</tt>.
+ * Global alignment score can be either used with two sequences or two sets of sequences of equal size.
  *
  * The same limitations to algorithms as in @link globalAlignment @endlink apply.  Furthermore, the
  * <tt>MyersBitVector</tt> and <tt>MyersHirschberg</tt> variants can only be used without any other parameter.
  *
+ * @section Parallel execution
+ *
+ * Some of the global alingment score functions are parallelized and vectorized and work on sets of sequences.
+ * The parallelization mode can be selected via the @link ExecutionPolicy @endlink as first argument.
+ * Following execution modes are possible: <i>sequential</i>, <i>parallel</i>, <i>wave-front</i>, <i>vectorized</i>,
+ * <i>parallel+vectorized</i> and <i>wave-front+vectorized</i>.
+ *
+ * The wave-front execution can be selected via the @link WavefrontExecutionPolicy @endlink, which can also be combined
+ * with a vectorized execution. In addition the wave-front execution parallelizes a single pairwise alignment, while the
+ * standard @link ParallelismTags#Parallel @endlink specialization does only parallelizes the sequence set via chunking.
+ * Note, the banded version is at the moment only supported for the following execution modes: <i>sequential</i>,
+ * <i>parallel</i>, <i>vectorized</i> and <i>parallel+vectorized</i>. At the moment the vectorized version only works
+ * reliable if all subject sequences and respectively all query sequences have the same length.
+ *
  * @see https://seqan.readthedocs.io/en/develop/Tutorial/Algorithms/Alignment/PairwiseSequenceAlignment.html
  * @see globalAlignment
+ *
+ * @datarace thread-safe. No shared state is modified during the execution and concurrent invocations of this function
+ * on the same data does not cause any race conditions.
  */
 
 // ----------------------------------------------------------------------------
@@ -496,11 +516,15 @@ template <typename TSequenceH,
           typename TScoreValue, typename TScoreSpec,
           bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec,
           typename TAlgoTag>
-TScoreValue globalAlignmentScore(TSequenceH const & seqH,
-                                 TSequenceV const & seqV,
-                                 Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                 AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & /*alignConfig*/,
-                                 TAlgoTag const & /*algoTag*/)
+SEQAN_FUNC_DISABLE_IF(And<And<Is<ContainerConcept<TSequenceH>>, Is<ContainerConcept<typename Value<TSequenceH>::Type>>>,
+                          And<Is<ContainerConcept<TSequenceV>>, Is<ContainerConcept<typename Value<TSequenceV>::Type>>>
+                         >,
+                      TScoreValue)
+globalAlignmentScore(TSequenceH const & seqH,
+                     TSequenceV const & seqV,
+                     Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                     AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & /*alignConfig*/,
+                     TAlgoTag const & /*algoTag*/)
 {
     typedef AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> TAlignConfig;
     typedef typename SubstituteAlignConfig_<TAlignConfig>::Type TFreeEndGaps;
@@ -517,7 +541,7 @@ template <typename TSequenceH,
           typename TSequenceV,
           typename TScoreValue, typename TScoreSpec,
           typename TAlgoTag>
-TScoreValue globalAlignmentScore(TSequenceH const & seqH,
+auto globalAlignmentScore(TSequenceH const & seqH,
                                  TSequenceV const & seqV,
                                  Score<TScoreValue, TScoreSpec> const & scoringScheme,
                                  TAlgoTag const & algoTag)
@@ -531,7 +555,7 @@ template <typename TSequenceH,
           typename TSequenceV,
           typename TScoreValue, typename TScoreSpec,
           bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec>
-TScoreValue globalAlignmentScore(TSequenceH const & seqH,
+auto globalAlignmentScore(TSequenceH const & seqH,
                                  TSequenceV const & seqV,
                                  Score<TScoreValue, TScoreSpec> const & scoringScheme,
                                  AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & alignConfig)
@@ -546,7 +570,7 @@ TScoreValue globalAlignmentScore(TSequenceH const & seqH,
 template <typename TSequenceH,
           typename TSequenceV,
           typename TScoreValue, typename TScoreSpec>
-TScoreValue globalAlignmentScore(TSequenceH const & seqH,
+auto globalAlignmentScore(TSequenceH const & seqH,
                                  TSequenceV const & seqV,
                                  Score<TScoreValue, TScoreSpec> const & scoringScheme)
 {
@@ -626,15 +650,20 @@ TScoreValue globalAlignmentScore(StringSet<TString, TSpec> const & strings,
 // Function globalAlignmentScore()       [unbanded, SIMD version, 2x StringSet]
 // ----------------------------------------------------------------------------
 
-template <typename TString1, typename TString2, typename TSpec,
+template <typename TSeqH,
+          typename TSeqV,
           typename TScoreValue, typename TScoreSpec,
           bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec,
           typename TAlgoTag>
-String<TScoreValue> globalAlignmentScore(StringSet<TString1, TSpec> const & stringsH,
-                                         StringSet<TString2, TSpec> const & stringsV,
-                                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                         AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & /*alignConfig*/,
-                                         TAlgoTag const & /*algoTag*/)
+SEQAN_FUNC_ENABLE_IF(And<And<Is<ContainerConcept<TSeqH>>, Is<ContainerConcept<typename Value<TSeqH>::Type>>>,
+                         And<Is<ContainerConcept<TSeqV>>, Is<ContainerConcept<typename Value<TSeqV>::Type>>>
+                        >,
+                    String<TScoreValue>)
+globalAlignmentScore(TSeqH const & stringsH,
+                     TSeqV const & stringsV,
+                     Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                     AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & /*alignConfig*/,
+                     TAlgoTag const & /*algoTag*/)
 {
     SEQAN_ASSERT_EQ(length(stringsH), length(stringsV));
     typedef AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> TAlignConfig;
@@ -645,45 +674,6 @@ String<TScoreValue> globalAlignmentScore(StringSet<TString1, TSpec> const & stri
     return _alignWrapper(stringsH, stringsV, scoringScheme, TAlignConfig2(), TGapModel());
 }
 
-// Interface without AlignConfig<>.
-template <typename TString1, typename TString2, typename TSpec,
-          typename TScoreValue, typename TScoreSpec,
-          typename TAlgoTag>
-String<TScoreValue> globalAlignmentScore(StringSet<TString1, TSpec> const & stringsH,
-                                         StringSet<TString2, TSpec> const & stringsV,
-                                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                         TAlgoTag const & algoTag)
-{
-    AlignConfig<> alignConfig;
-    return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, algoTag);
-}
-
-// Interface without algorithm tag.
-template <typename TString1, typename TString2, typename TSpec,
-          typename TScoreValue, typename TScoreSpec,
-          bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec>
-String<TScoreValue> globalAlignmentScore(StringSet<TString1, TSpec> const & stringsH,
-                                         StringSet<TString2, TSpec> const & stringsV,
-                                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
-                                         AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & alignConfig)
-{
-    if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme))
-        return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, NeedlemanWunsch());
-    else
-        return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig, Gotoh());
-}
-
-// Interface without AlignConfig<> and algorithm tag.
-template <typename TString1, typename TString2, typename TSpec,
-          typename TScoreValue, typename TScoreSpec>
-String<TScoreValue> globalAlignmentScore(StringSet<TString1, TSpec> const & stringsH,
-                                         StringSet<TString2, TSpec> const & stringsV,
-                                         Score<TScoreValue, TScoreSpec> const & scoringScheme)
-{
-    AlignConfig<> alignConfig;
-    return globalAlignmentScore(stringsH, stringsV, scoringScheme, alignConfig);
-}
-
 // --------------------------------------------------------------------------------
 // Function globalAlignmentScore()    [unbanded, SIMD version, String vs StringSet]
 // --------------------------------------------------------------------------------
@@ -755,7 +745,7 @@ String<TScoreValue> globalAlignmentScore(TString1 const & stringH,
 template <typename TSequenceH, typename TGapsSpecH, typename TSetSpecH,
           typename TSequenceV, typename TGapsSpecV, typename TSetSpecV,
           typename TScoreValue, typename TScoreSpec,
-          bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec, 
+          bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec,
           typename TAlgoTag>
 inline auto
 globalAlignment(StringSet<Gaps<TSequenceH, TGapsSpecH>, TSetSpecH> & gapSeqSetH,
@@ -772,6 +762,34 @@ globalAlignment(StringSet<Gaps<TSequenceH, TGapsSpecH>, TSetSpecH> & gapSeqSetH,
     return _alignWrapper(gapSeqSetH, gapSeqSetV, scoringScheme, TAlignConfig2(), TGapModel());
 }
 
+// Interface without algorithm tag.
+template <typename TSequenceH, typename TGapsSpecH, typename TSetSpecH,
+          typename TSequenceV, typename TGapsSpecV, typename TSetSpecV,
+          typename TScoreValue, typename TScoreSpec,
+          bool TOP, bool LEFT, bool RIGHT, bool BOTTOM, typename TACSpec>
+String<TScoreValue> globalAlignment(StringSet<Gaps<TSequenceH, TGapsSpecH>, TSetSpecH> & gapSeqSetH,
+                                    StringSet<Gaps<TSequenceV, TGapsSpecV>, TSetSpecV> & gapSeqSetV,
+                                    Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                                    AlignConfig<TOP, LEFT, RIGHT, BOTTOM, TACSpec> const & alignConfig)
+{
+    if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme))
+        return globalAlignment(gapSeqSetH, gapSeqSetV, scoringScheme, alignConfig, NeedlemanWunsch());
+    else
+        return globalAlignment(gapSeqSetH, gapSeqSetV, scoringScheme, alignConfig, Gotoh());
+}
+
+// Interface without AlignConfig<> and algorithm tag.
+template <typename TSequenceH, typename TGapsSpecH, typename TSetSpecH,
+          typename TSequenceV, typename TGapsSpecV, typename TSetSpecV,
+          typename TScoreValue, typename TScoreSpec>
+String<TScoreValue> globalAlignment(StringSet<Gaps<TSequenceH, TGapsSpecH>, TSetSpecH> & gapSeqSetH,
+                                    StringSet<Gaps<TSequenceV, TGapsSpecV>, TSetSpecV> & gapSeqSetV,
+                                    Score<TScoreValue, TScoreSpec> const & scoringScheme)
+{
+    AlignConfig<> alignConfig;
+    return globalAlignment(gapSeqSetH, gapSeqSetV, scoringScheme, alignConfig);
+}
+
 // ----------------------------------------------------------------------------
 // Function globalAlignment()        [unbanded, SIMD version, StringSet<Align>]
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/align/local_alignment_banded.h b/include/seqan/align/local_alignment_banded.h
index 8edcfd5..416e4b7 100644
--- a/include/seqan/align/local_alignment_banded.h
+++ b/include/seqan/align/local_alignment_banded.h
@@ -271,13 +271,13 @@ localAlignment(StringSet<Align<TSequence, TAlignSpec>, TSetSpec> & alignSet,
     StringSet<TGapSequence, Dependent<> > gapSetV;
     reserve(gapSetH, length(alignSet));
     reserve(gapSetV, length(alignSet));
-    
+
     for (auto & align : alignSet)
     {
         appendValue(gapSetH, row(align, 0));
         appendValue(gapSetV, row(align, 1));
     }
-    
+
     return localAlignment(gapSetH, gapSetV, scoringScheme, lowerDiag, upperDiag, algoTag);
 }
 
@@ -293,6 +293,75 @@ String<TScoreValue> localAlignment(StringSet<Align<TSequence, TAlignSpec> > & al
         return localAlignment(align, scoringScheme, lowerDiag, upperDiag, LinearGaps());
 }
 
+// ----------------------------------------------------------------------------
+// Function localAlignmentScore()                  [banded, no-simd, TSequence]
+// ----------------------------------------------------------------------------
+
+template <typename TSequenceH,
+          typename TSequenceV,
+          typename TScoreValue, typename TScoreSpec,
+          typename TAlgoTag>
+SEQAN_FUNC_DISABLE_IF(And<And<Is<ContainerConcept<TSequenceH>>, Is<ContainerConcept<typename Value<TSequenceH>::Type>>>,
+                          And<Is<ContainerConcept<TSequenceV>>, Is<ContainerConcept<typename Value<TSequenceV>::Type>>>
+                         >, TScoreValue)
+localAlignmentScore(TSequenceH const & seqH,
+                    TSequenceV const & seqV,
+                    Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                    int const lowerDiag,
+                    int const upperDiag,
+                    TAlgoTag const & /*algoTag*/)
+{
+    typedef AlignConfig2<DPLocal, DPBandConfig<BandOn>, FreeEndGaps_<>, TracebackOff> TAlignConfig2;
+    typedef typename SubstituteAlgoTag_<TAlgoTag>::Type TGapModel;
+
+    DPScoutState_<Default> dpScoutState;
+    String<TraceSegment_<unsigned, unsigned> > traceSegments;  // Dummy segments.
+    return _setUpAndRunAlignment(traceSegments, dpScoutState, seqH, seqV, scoringScheme,
+                                 TAlignConfig2{lowerDiag, upperDiag}, TGapModel{});
+}
+
+// ----------------------------------------------------------------------------
+// Function localAlignmentScore()                     [banded, Simd, TSequence]
+// ----------------------------------------------------------------------------
+
+template <typename TSeqH,
+          typename TSeqV,
+          typename TScoreValue, typename TScoreSpec,
+          typename TAlgoTag>
+inline
+SEQAN_FUNC_ENABLE_IF(And<And<Is<ContainerConcept<TSeqH>>, Is<ContainerConcept<typename Value<TSeqH>::Type>>>,
+                         And<Is<ContainerConcept<TSeqV>>, Is<ContainerConcept<typename Value<TSeqV>::Type>>>
+                        >, String<TScoreValue>)
+localAlignmentScore(TSeqH const & stringsH,
+                    TSeqV const & stringsV,
+                    Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                    int const lowerDiag,
+                    int const upperDiag,
+                    TAlgoTag const & /*algoTag*/)
+{
+    typedef AlignConfig2<DPLocal, DPBandConfig<BandOn>, FreeEndGaps_<>, TracebackOff> TAlignConfig2;
+    typedef typename SubstituteAlgoTag_<TAlgoTag>::Type TGapModel;
+
+    SEQAN_ASSERT_EQ(length(stringsH), length(stringsV));
+    return _alignWrapper(stringsH, stringsV, scoringScheme, TAlignConfig2{lowerDiag, upperDiag}, TGapModel());
+}
+
+// Interface without algorithm tag.
+template <typename TSequenceH,
+          typename TSequenceV,
+          typename TScoreValue, typename TScoreSpec>
+auto localAlignmentScore(TSequenceH const & seqH,
+                         TSequenceV const & seqV,
+                         Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                         int const lowerDiag,
+                         int const upperDiag)
+{
+    if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme))
+        return localAlignmentScore(seqH, seqV, scoringScheme, lowerDiag, upperDiag, NeedlemanWunsch());
+    else
+        return localAlignmentScore(seqH, seqV, scoringScheme, lowerDiag, upperDiag, Gotoh());
+}
+
 }  // namespace seqan
 
 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_LOCAL_ALIGNMENT_BANDED_H_
diff --git a/include/seqan/align/local_alignment_unbanded.h b/include/seqan/align/local_alignment_unbanded.h
index a6a920f..4dbf9a7 100644
--- a/include/seqan/align/local_alignment_unbanded.h
+++ b/include/seqan/align/local_alignment_unbanded.h
@@ -355,13 +355,13 @@ localAlignment(StringSet<Align<TSequence, TAlignSpec> > & alignSet,
     StringSet<TGapSequence, Dependent<> > gapSetV;
     reserve(gapSetH, length(alignSet));
     reserve(gapSetV, length(alignSet));
-    
+
     for (auto & align : alignSet)
     {
         appendValue(gapSetH, row(align, 0));
         appendValue(gapSetV, row(align, 1));
     }
-    
+
     return localAlignment(gapSetH, gapSetV, scoringScheme, algoTag);
 }
 
@@ -376,6 +376,111 @@ String<TScoreValue> localAlignment(StringSet<Align<TSequence, TAlignSpec> > & al
         return localAlignment(align, scoringScheme, LinearGaps());
 }
 
+// ----------------------------------------------------------------------------
+// Function localAlignmentScore()                         [unbanded, TSequence]
+// ----------------------------------------------------------------------------
+
+/*!
+ * @fn localAlignmentScore
+ * @headerfile <seqan/align.h>
+ * @brief Computes the best global pairwise alignment score.
+ *
+ * @signature TScoreVal localAlignmentScore([exec,] subject, query, scoringScheme[, lowerDiag, upperDiag]);
+ *
+ * @param[in] exec          @link ExecutionPolicy Policy at endlink to select execution mode of alignment algorithm.
+ * @param[in] subject       Subject sequence(s) (horizontal in alignment matrix). Must satisfy @link ContainerConcept @endlink or container-of-container concept.
+ * @param[in] query         Query sequence(s) (vertical in alignment matrix). Must satisfy @link ContainerConcept @endlink or container-of-container concept.
+ * @param[in] scoringScheme The scoring scheme to use for the alignment.  Note that the user is responsible for ensuring
+ *                          that the scoring scheme is compatible with <tt>algorithmTag</tt>.  Type: @link Score @endlink.
+ * @param[in] lowerDiag     Optional lower diagonal.  Types: <tt>int</tt>
+ * @param[in] upperDiag     Optional upper diagonal.  Types: <tt>int</tt>
+ *
+ * @return TScoreVal   Score value of the resulting alignment  (Metafunction: @link Score#Value @endlink of
+ *                     the type of <tt>scoringScheme</tt>). If subject and query are sets the function returns a
+ *                     set of scores representing the score for each pairwise alignment (<tt>subject[i]</tt> with <tt>query[i]</tt>).
+ *
+ * This function does not perform the (linear time) traceback step after the (mostly quadratic time) dynamic programming
+ * step. Local alignment score can be either used with two sequences or two sets of sequences of equal size.
+ *
+ * @section Parallel execution
+ *
+ * Some of the local alingment score functions are parallelized and vectorized.
+ * The parallelization mode can be selected via the @link ExecutionPolicy @endlink as first argument.
+ * Following execution modes are possible: <i>sequential</i>, <i>parallel</i>, <i>wave-front</i>, <i>vectorized</i>,
+ * <i>parallel+vectorized</i> and <i>wave-front+vectorized</i>.
+ *
+ * The wave-front execution can be selected via the @link WavefrontExecutionPolicy @endlink, which can also be combined
+ * with a vectorized execution. In addition the wave-front execution parallelizes a single pairwise alignment, while the
+ * standard @link ParallelismTags#Parallel @endlink specialization does only parallelizes the sequence set via chunking.
+ * Note, the banded version is at the moment only supported for the following execution modes: <i>sequential</i>,
+ * <i>parallel</i>, <i>vectorized</i> and <i>parallel+vectorized</i>. At the moment the vectorized version only works
+ * reliable if all subject sequences and respectively all query sequences have the same length.
+ *
+ * @see https://seqan.readthedocs.io/en/develop/Tutorial/Algorithms/Alignment/PairwiseSequenceAlignment.html
+ * @see localAlignment
+ *
+ * @datarace thread-safe. No shared state is modified during the execution and concurrent invocations of this function
+ * on the same data does not cause any race conditions.
+ */
+
+template <typename TSequenceH,
+          typename TSequenceV,
+          typename TScoreValue, typename TScoreSpec,
+          typename TAlgoTag>
+SEQAN_FUNC_DISABLE_IF(And<And<Is<ContainerConcept<TSequenceH>>, Is<ContainerConcept<typename Value<TSequenceH>::Type>>>,
+                          And<Is<ContainerConcept<TSequenceV>>, Is<ContainerConcept<typename Value<TSequenceV>::Type>>>
+                         >, TScoreValue)
+localAlignmentScore(TSequenceH const & seqH,
+                    TSequenceV const & seqV,
+                    Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                    TAlgoTag const & /*algoTag*/)
+{
+    typedef AlignConfig2<DPLocal, DPBandConfig<BandOff>, FreeEndGaps_<>, TracebackOff> TAlignConfig2;
+    typedef typename SubstituteAlgoTag_<TAlgoTag>::Type TGapModel;
+
+    DPScoutState_<Default> dpScoutState;
+    String<TraceSegment_<unsigned, unsigned> > traceSegments;  // Dummy segments.
+    return _setUpAndRunAlignment(traceSegments, dpScoutState, seqH, seqV, scoringScheme, TAlignConfig2{}, TGapModel{});
+}
+
+// ----------------------------------------------------------------------------
+// Function localAlignmentScore()                   [unbanded, Simd, TSequence]
+// ----------------------------------------------------------------------------
+
+template <typename TSeqH,
+          typename TSeqV,
+          typename TScoreValue, typename TScoreSpec,
+          typename TAlgoTag>
+inline
+SEQAN_FUNC_ENABLE_IF(And<And<Is<ContainerConcept<TSeqH>>, Is<ContainerConcept<typename Value<TSeqH>::Type>>>,
+                         And<Is<ContainerConcept<TSeqV>>, Is<ContainerConcept<typename Value<TSeqV>::Type>>>
+                        >, String<TScoreValue>)
+localAlignmentScore(TSeqH const & stringsH,
+                    TSeqV const & stringsV,
+                    Score<TScoreValue, TScoreSpec> const & scoringScheme,
+                    TAlgoTag const & /*algoTag*/)
+{
+    SEQAN_ASSERT_EQ(length(stringsH), length(stringsV));
+    typedef AlignConfig2<DPLocal, DPBandConfig<BandOff>, FreeEndGaps_<>, TracebackOff> TAlignConfig2;
+    typedef typename SubstituteAlgoTag_<TAlgoTag>::Type TGapModel;
+
+    return _alignWrapper(stringsH, stringsV, scoringScheme, TAlignConfig2(), TGapModel());
+}
+
+// Interface without algorithm tag.
+template <typename TSequenceH,
+          typename TSequenceV,
+          typename TScoreValue, typename TScoreSpec>
+auto localAlignmentScore(TSequenceH const & seqH,
+                         TSequenceV const & seqV,
+                         Score<TScoreValue, TScoreSpec> const & scoringScheme)
+{
+    if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme))
+        return localAlignmentScore(seqH, seqV, scoringScheme, NeedlemanWunsch());
+    else
+        return localAlignmentScore(seqH, seqV, scoringScheme, Gotoh());
+}
+
 }  // namespace seqan
 
 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_LOCAL_ALIGNMENT_UNBANDED_H_
diff --git a/include/seqan/align/local_alignment_waterman_eggert_impl.h b/include/seqan/align/local_alignment_waterman_eggert_impl.h
index d80cfc3..741ca30 100644
--- a/include/seqan/align/local_alignment_waterman_eggert_impl.h
+++ b/include/seqan/align/local_alignment_waterman_eggert_impl.h
@@ -188,12 +188,12 @@ TScoreValue getScore(LocalAlignmentFinder<TScoreValue> const & sw)
 // Function _smithWatermanGetMatrix()
 // ----------------------------------------------------------------------------
 
-template <typename TScoreValue, typename TStringH, typename TStringV>
+template <typename TScoreValue, typename TScoreSpec, typename TStringH, typename TStringV>
 TScoreValue
 _smithWatermanGetMatrix(LocalAlignmentFinder<TScoreValue> & sw,
                         TStringH const & strH,
                         TStringV const & strV,
-                        Score<TScoreValue, Simple> const & score_,
+                        Score<TScoreValue, TScoreSpec> const & score_,
                         TScoreValue cutoff)
 {
     // typedefs
@@ -220,8 +220,6 @@ _smithWatermanGetMatrix(LocalAlignmentFinder<TScoreValue> & sw,
     TStringIteratorH x = x_end;
     TStringIteratorV y;
 
-    TScoreValue score_match = scoreMatch(score_);
-    TScoreValue score_mismatch = scoreMismatch(score_);
     TScoreValue score_gap = scoreGapExtend(score_);
 
     TScoreValue h = 0;
@@ -263,14 +261,15 @@ _smithWatermanGetMatrix(LocalAlignmentFinder<TScoreValue> & sw,
             goPrevious(finger1, 0);
             goPrevious(finger2, 0);
 
+            TScoreValue currScore = score(score_, *x, cy);
             if (*x == cy)
             {
-                v = h + score_match;
+                v = h + currScore;
                 h = *finger2;
             }
             else
             {
-                TScoreValue s1 = h + score_mismatch;
+                TScoreValue s1 = h + currScore;
                 h = *finger2;
                 TScoreValue s2 = score_gap + ((h > v) ? h : v);
                 v = (s1 > s2) ? s1 : s2;
@@ -303,12 +302,15 @@ _smithWatermanGetMatrix(LocalAlignmentFinder<TScoreValue> & sw,
 // ----------------------------------------------------------------------------
 
 // declumping
-template <typename TScoreValue, typename TSequenceH, typename TGapsSpecH, typename TSequenceV, typename TGapsSpecV>
+template <typename TScoreValue,
+          typename TSequenceH, typename TGapsSpecH,
+          typename TSequenceV, typename TGapsSpecV,
+          typename TScoreSpec>
 void
 _smithWatermanDeclump(LocalAlignmentFinder<TScoreValue> & sw ,
                       Gaps<TSequenceH, TGapsSpecH> & gapsH,
                       Gaps<TSequenceV, TGapsSpecV> & gapsV,
-                      Score<TScoreValue, Simple> const & score_)
+                      Score<TScoreValue, TScoreSpec> const & score_)
 {
 //-------------------------------------------------------------------------
 //typedefs
@@ -364,8 +366,6 @@ _smithWatermanDeclump(LocalAlignmentFinder<TScoreValue> & sw ,
     TSequenceHIter x_stop = x_end;
 
 
-    TScoreValue score_match = scoreMatch(score_);
-    TScoreValue score_mismatch = scoreMismatch(score_);
     TScoreValue score_gap = scoreGapExtend(score_);
     TScoreValue h,v;
 
@@ -456,9 +456,10 @@ _smithWatermanDeclump(LocalAlignmentFinder<TScoreValue> & sw ,
         {
             goPrevious(finger0, 0);
             goPrevious(finger1, 0);
+            TScoreValue currScore = score(score_, *x, cy);
             if (*x == cy && !(sw.forbidden[position(finger0)]))
             {
-                v = h + score_match;
+                v = h + currScore;
                 h = *finger1;
             }
             else
@@ -474,7 +475,7 @@ _smithWatermanDeclump(LocalAlignmentFinder<TScoreValue> & sw ,
                 else
                 {
                     if(sw.forbidden[position(finger0)]) s1 = 0;
-                    else s1 = h + score_mismatch;
+                    else s1 = h + currScore;
                 }
 
                 h = *finger1;
@@ -522,13 +523,16 @@ _smithWatermanDeclump(LocalAlignmentFinder<TScoreValue> & sw ,
 // ----------------------------------------------------------------------------
 
 // Traceback.
-template <typename TSourceH, typename TGapsSpecH, typename TSourceV, typename TGapsSpecV, typename TScoreValue, unsigned DIMENSION>
+template <typename TSourceH, typename TGapsSpecH,
+          typename TSourceV, typename TGapsSpecV,
+          typename TScoreValue, typename TScoreSpec,
+          unsigned DIMENSION>
 typename Iterator<Matrix<TScoreValue, DIMENSION>, Standard >::Type
 _smithWatermanTrace(Gaps<TSourceH, TGapsSpecH> & gapsH,
                     Gaps<TSourceV, TGapsSpecV> & gapsV,
                     typename LocalAlignmentFinder<TScoreValue>::TBoolMatrix & fb_matrix,
                     Iter< Matrix<TScoreValue, DIMENSION>, PositionIterator > source_,
-                    Score<TScoreValue, Simple> const & scoring_) {
+                    Score<TScoreValue, TScoreSpec> const & scoring_) {
     //typedefs
     typedef Iter<Matrix<TScoreValue, DIMENSION>, PositionIterator > TMatrixIterator;
     typedef typename Position<Matrix<TScoreValue, DIMENSION> >::Type TPosition;
@@ -559,7 +563,6 @@ _smithWatermanTrace(Gaps<TSourceH, TGapsSpecH> & gapsH,
     TSourceIteratorV it_1 = iter(strV, pos_1, Standard());
     TSourceIteratorV it_1_end = end(strV);
 
-    TScoreValue score_mismatch = scoreMismatch(scoring_);
     TScoreValue score_gap = scoreGapExtend(scoring_);
 
     //-------------------------------------------------------------------------
@@ -586,7 +589,7 @@ _smithWatermanTrace(Gaps<TSourceH, TGapsSpecH> & gapsH,
                 d = 0;
             else{
                 goNext(it_, 1);
-                d = *it_ + score_mismatch;
+                d = *it_ + score(scoring_, *it_0, *it_1);
             }
 
             it_ = source_;
@@ -678,7 +681,9 @@ _getNextBestEndPosition(LocalAlignmentFinder<TScoreValue> & sw ,
 // ----------------------------------------------------------------------------
 
 // Wrapper that computes the matrix and does the backtracking for the best alignment
-template <typename TSourceH, typename TGapsSpecH, typename TSourceV, typename TGapsSpecV, typename TScoreValue, typename TScoreSpec>
+template <typename TSourceH, typename TGapsSpecH,
+          typename TSourceV, typename TGapsSpecV,
+          typename TScoreValue, typename TScoreSpec>
 TScoreValue
 _smithWaterman(Gaps<TSourceH, TGapsSpecH> & gapsH,
                Gaps<TSourceV, TGapsSpecV> & gapsV,
diff --git a/include/seqan/align/matrix_base.h b/include/seqan/align/matrix_base.h
index e5ca253..2995bf9 100644
--- a/include/seqan/align/matrix_base.h
+++ b/include/seqan/align/matrix_base.h
@@ -45,34 +45,32 @@ namespace seqan
 struct NDimensional;
 
 
-template <typename TValue, unsigned DIMENSION = 0/*typename TSpec = NDimensional*/>
+template <typename TValue, unsigned DIMENSION = 0/*typename TSpec = NDimensional*/, typename THost = String<TValue> >
 class Matrix;
 
 //////////////////////////////////////////////////////////////////////////////
 template <typename T> struct SizeArr_;
 
-template <typename TValue, unsigned DIMENSION>
-struct SizeArr_<Matrix<TValue, DIMENSION> >
+template <typename TValue, unsigned DIMENSION, typename THost>
+struct SizeArr_<Matrix<TValue, DIMENSION, THost> >
 {
-    typedef Matrix<TValue, DIMENSION> TMatrix_;
+    typedef Matrix<TValue, DIMENSION, THost> TMatrix_;
     typedef typename Size<TMatrix_>::Type TSize_;
     typedef String<TSize_> Type;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION>
-struct Host<Matrix<TValue, DIMENSION> >
+template <typename TValue, unsigned DIMENSION, typename THost>
+struct Host<Matrix<TValue, DIMENSION, THost> >
 {
-    typedef typename StringSpecForValue_<TValue>::Type TSpec_;
-    typedef String<TValue, TSpec_> Type;
+    typedef THost Type;
 };
 
-template <typename TValue, unsigned DIMENSION>
-struct Host<Matrix<TValue, DIMENSION> const>
+template <typename TValue, unsigned DIMENSION, typename THost>
+struct Host<Matrix<TValue, DIMENSION, THost> const>
 {
-    typedef typename StringSpecForValue_<TValue>::Type TSpec_;
-    typedef String<TValue, TSpec_> Type;
+    typedef THost const Type;
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -94,15 +92,14 @@ struct Host<Matrix<TValue, DIMENSION> const>
  */
 
 
-template <typename TValue>
-class Matrix<TValue, 0>
+template <typename TValue, typename THost>
+class Matrix<TValue, 0, THost>
 {
 //____________________________________________________________________________
 
 public:
     typedef typename Size<Matrix>::Type TSize;
     typedef String<TSize> TSizeArr;
-    typedef typename Host<Matrix>::Type THost;
 
     TSizeArr data_lengths;        //Length of every dimension
     TSizeArr data_factors;        //used for positions of dimensions in host ("size of jumps" to get to next entry of specified dimension)
@@ -158,15 +155,14 @@ public:
 };
 
 
-template <typename TValue>
-class Matrix<TValue, 2>
+template <typename TValue, typename THost>
+class Matrix<TValue, 2, THost>
 {
 //____________________________________________________________________________
 
 public:
     typedef typename Size<Matrix>::Type TSize;
     typedef String<TSize> TSizeArr;
-    typedef typename Host<Matrix>::Type THost;
 
     TSizeArr data_lengths;
     TSizeArr data_factors;
@@ -219,15 +215,14 @@ public:
 //____________________________________________________________________________
 };
 
-template <typename TValue>
-class Matrix<TValue, 3>
+template <typename TValue, typename THost>
+class Matrix<TValue, 3, THost>
 {
 //____________________________________________________________________________
 
 public:
     typedef typename Size<Matrix>::Type TSize;
-    typedef String<TSize> TSizeArr; 
-    typedef typename Host<Matrix>::Type THost;
+    typedef String<TSize> TSizeArr;
 
     TSizeArr data_lengths;
     TSizeArr data_factors;
@@ -280,30 +275,30 @@ public:
 //____________________________________________________________________________
 };
 
-template <typename TValue, unsigned DIMENSION>
-inline typename SizeArr_<Matrix<TValue, DIMENSION> >::Type &
-_dataLengths(Matrix<TValue, DIMENSION> & me)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename SizeArr_<Matrix<TValue, DIMENSION, THost> >::Type &
+_dataLengths(Matrix<TValue, DIMENSION, THost> & me)
 {
     return me.data_lengths;
 }
 
-template <typename TValue, unsigned DIMENSION>
-inline typename SizeArr_<Matrix<TValue, DIMENSION> >::Type const &
-_dataLengths(Matrix<TValue, DIMENSION> const & me)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename SizeArr_<Matrix<TValue, DIMENSION, THost> >::Type const &
+_dataLengths(Matrix<TValue, DIMENSION, THost> const & me)
 {
     return me.data_lengths;
 }
 
-template <typename TValue, unsigned DIMENSION>
-inline typename SizeArr_<Matrix<TValue, DIMENSION> >::Type &
-_dataFactors(Matrix<TValue, DIMENSION> & me)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename SizeArr_<Matrix<TValue, DIMENSION, THost> >::Type &
+_dataFactors(Matrix<TValue, DIMENSION, THost> & me)
 {
     return me.data_factors;
 }
 
-template <typename TValue, unsigned DIMENSION>
-inline typename SizeArr_<Matrix<TValue, DIMENSION> >::Type const &
-_dataFactors(Matrix<TValue, DIMENSION> const & me)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename SizeArr_<Matrix<TValue, DIMENSION, THost> >::Type const &
+_dataFactors(Matrix<TValue, DIMENSION, THost> const & me)
 {
     return me.data_factors;
 }
@@ -311,25 +306,25 @@ _dataFactors(Matrix<TValue, DIMENSION> const & me)
 //____________________________________________________________________________
 
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline bool
-dependent(Matrix<TValue, DIMENSION> & me)
+dependent(Matrix<TValue, DIMENSION, THost> & me)
 {
     return dependent(me.data_host);
 }
 
 //____________________________________________________________________________
 
-template <typename TValue, unsigned DIMENSION>
-inline Holder<typename Host<Matrix<TValue, DIMENSION> >::Type> &
-_dataHost(Matrix<TValue, DIMENSION> & matrix)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline Holder<typename Host<Matrix<TValue, DIMENSION, THost> >::Type> &
+_dataHost(Matrix<TValue, DIMENSION, THost> & matrix)
 {
     return matrix.data_host;
 }
 
-template <typename TValue, unsigned DIMENSION>
-inline Holder<typename Host<Matrix<TValue, DIMENSION> >::Type> const &
-_dataHost(Matrix<TValue, DIMENSION> const & matrix)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline Holder<typename Host<Matrix<TValue, DIMENSION, THost> >::Type> const &
+_dataHost(Matrix<TValue, DIMENSION, THost> const & matrix)
 {
     return matrix.data_host;
 }
@@ -338,7 +333,7 @@ _dataHost(Matrix<TValue, DIMENSION> const & matrix)
 
 template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-assignHost(Matrix<TValue, DIMENSION> & me, THost const & value_)
+assignHost(Matrix<TValue, DIMENSION, THost> & me, THost const & value_)
 {
     assignValue(me.data_host, value_);
 }
@@ -347,48 +342,48 @@ assignHost(Matrix<TValue, DIMENSION> & me, THost const & value_)
 
 template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-moveHost(Matrix<TValue, DIMENSION> & me, THost const & value_)
+moveHost(Matrix<TValue, DIMENSION, THost> & me, THost const & value_)
 {
     moveValue(me.data_host, value_);
 }
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION>
-struct Value< Matrix<TValue, DIMENSION> >
+template <typename TValue, unsigned DIMENSION, typename THost>
+struct Value< Matrix<TValue, DIMENSION, THost> >
 {
     typedef TValue Type;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TIteratorSpec>
-struct Iterator< Matrix<TValue, DIMENSION>, TIteratorSpec >
+template <typename TValue, unsigned DIMENSION, typename THost, typename TIteratorSpec>
+struct Iterator< Matrix<TValue, DIMENSION, THost>, TIteratorSpec >
 {
-    typedef Iter<Matrix<TValue, DIMENSION>, PositionIterator> Type;
+    typedef Iter<Matrix<TValue, DIMENSION, THost>, PositionIterator> Type;
 };
 
-template <typename TValue, unsigned DIMENSION, typename TIteratorSpec>
-struct Iterator< Matrix<TValue, DIMENSION> const, TIteratorSpec >
+template <typename TValue, unsigned DIMENSION, typename THost, typename TIteratorSpec>
+struct Iterator< Matrix<TValue, DIMENSION, THost> const, TIteratorSpec >
 {
-    typedef Iter<Matrix<TValue, DIMENSION> const, PositionIterator> Type;
+    typedef Iter<Matrix<TValue, DIMENSION, THost> const, PositionIterator> Type;
 };
 
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION>
-inline typename Size<Matrix<TValue, DIMENSION> const>::Type
-dimension(Matrix<TValue, DIMENSION> const & me)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename Size<Matrix<TValue, DIMENSION, THost> const>::Type
+dimension(Matrix<TValue, DIMENSION, THost> const & me)
 {
     return length(_dataLengths(me));
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-setDimension(Matrix<TValue, DIMENSION> & me,
+setDimension(Matrix<TValue, DIMENSION, THost> & me,
              unsigned int dim_)
 {
 
@@ -403,39 +398,39 @@ setDimension(Matrix<TValue, DIMENSION> & me,
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION>
-inline typename Size<Matrix<TValue, DIMENSION> >::Type
-length(Matrix<TValue, DIMENSION> const & me,
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename Size<Matrix<TValue, DIMENSION, THost> >::Type
+length(Matrix<TValue, DIMENSION, THost> const & me,
        unsigned int dim_)
 {
     return me.data_lengths[dim_];
 }
 
-template <typename TValue, unsigned DIMENSION>
-inline typename Size<Matrix <TValue, DIMENSION> >::Type
-length(Matrix<TValue, DIMENSION> const & me)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename Size<Matrix <TValue, DIMENSION, THost> >::Type
+length(Matrix<TValue, DIMENSION, THost> const & me)
 {
     return length(host(me));
 }
 
-template <typename TValue, unsigned DIMENSION>
-inline bool empty(Matrix<TValue, DIMENSION> const & me)
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline bool empty(Matrix<TValue, DIMENSION, THost> const & me)
 {
     return empty(host(me));
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TLength>
+template <typename TValue, unsigned DIMENSION, typename THost, typename TLength>
 inline void
-setLength(Matrix<TValue, DIMENSION> & me,
+setLength(Matrix<TValue, DIMENSION, THost> & me,
           unsigned int dim_,
           TLength length_)
 {
     SEQAN_ASSERT_GT(length_, static_cast<TLength>(0));
     SEQAN_ASSERT_LT(dim_, dimension(me));
 
-    typedef typename SizeArr_<Matrix<TValue, DIMENSION> >::TSize_ TSize_;
+    typedef typename SizeArr_<Matrix<TValue, DIMENSION, THost> >::TSize_ TSize_;
 
     _dataLengths(me)[dim_] = static_cast<TSize_>(length_);
 }
@@ -453,11 +448,11 @@ setLength(Matrix<TValue, DIMENSION> & me,
  */
 
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-resize(Matrix<TValue, DIMENSION> & me)
+resize(Matrix<TValue, DIMENSION, THost> & me)
 {
-    typedef Matrix<TValue, DIMENSION> TMatrix;
+    typedef Matrix<TValue, DIMENSION, THost> TMatrix;
     typedef typename Size<TMatrix>::Type TSize;
 
     unsigned int dimension_ = dimension(me);
@@ -479,11 +474,11 @@ resize(Matrix<TValue, DIMENSION> & me)
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TFillValue>
+template <typename TValue, unsigned DIMENSION, typename THost, typename TFillValue>
 inline void
-resize(Matrix<TValue, DIMENSION> & me, TFillValue myValue)    //resize the matrix and fill with value
+resize(Matrix<TValue, DIMENSION, THost> & me, TFillValue myValue)    //resize the matrix and fill with value
 {
-    typedef Matrix<TValue, DIMENSION> TMatrix;
+    typedef Matrix<TValue, DIMENSION, THost> TMatrix;
     typedef typename Size<TMatrix>::Type TSize;
 
     unsigned int dimension_ = dimension(me);
@@ -504,36 +499,36 @@ resize(Matrix<TValue, DIMENSION> & me, TFillValue myValue)    //resize the matri
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TPosition>
-inline typename Position<Matrix <TValue, DIMENSION> >::Type
-nextPosition(Matrix<TValue, DIMENSION> & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition>
+inline typename Position<Matrix <TValue, DIMENSION, THost> >::Type
+nextPosition(Matrix<TValue, DIMENSION, THost> & me,
              TPosition position_,
              unsigned int dimension_)
 {
     return position_ + _dataFactors(me)[dimension_];
 }
 
-template <typename TValue, unsigned DIMENSION, typename TPosition>
-inline typename Position<Matrix <TValue, DIMENSION> >::Type
-nextPosition(Matrix<TValue, DIMENSION> const & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition>
+inline typename Position<Matrix <TValue, DIMENSION, THost> >::Type
+nextPosition(Matrix<TValue, DIMENSION, THost> const & me,
              TPosition position_,
              unsigned int dimension_)
 {
     return position_ + _dataFactors(me)[dimension_];
 }
 
-template <typename TValue, unsigned DIMENSION, typename TPosition>
-inline typename Position<Matrix <TValue, DIMENSION> >::Type
-previousPosition(Matrix<TValue, DIMENSION> & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition>
+inline typename Position<Matrix <TValue, DIMENSION, THost> >::Type
+previousPosition(Matrix<TValue, DIMENSION, THost> & me,
                  TPosition position_,
                  unsigned int dimension_)
 {
     return position_ - _dataFactors(me)[dimension_];
 }
 
-template <typename TValue, unsigned DIMENSION, typename TPosition>
-inline typename Position<Matrix <TValue, DIMENSION> >::Type
-previousPosition(Matrix<TValue, DIMENSION> const & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition>
+inline typename Position<Matrix <TValue, DIMENSION, THost> >::Type
+previousPosition(Matrix<TValue, DIMENSION, THost> const & me,
                  TPosition position_,
                  unsigned int dimension_)
 {
@@ -542,9 +537,9 @@ previousPosition(Matrix<TValue, DIMENSION> const & me,
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TPosition>
-inline typename Size< Matrix <TValue, DIMENSION> >::Type
-coordinate(Matrix<TValue, DIMENSION> const & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition>
+inline typename Size< Matrix <TValue, DIMENSION, THost> >::Type
+coordinate(Matrix<TValue, DIMENSION, THost> const & me,
            TPosition position_,
            unsigned int dimension_)
 {
@@ -562,51 +557,51 @@ coordinate(Matrix<TValue, DIMENSION> const & me,
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TTag>
-inline typename Iterator<Matrix <TValue, DIMENSION>, Tag<TTag> const>::Type
-begin(Matrix<TValue, DIMENSION> & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TTag>
+inline typename Iterator<Matrix <TValue, DIMENSION, THost>, Tag<TTag> const>::Type
+begin(Matrix<TValue, DIMENSION, THost> & me,
       Tag<TTag> const)
 {
-    return typename Iterator<Matrix <TValue, DIMENSION>, Tag<TTag> const >::Type(me, 0);
+    return typename Iterator<Matrix <TValue, DIMENSION, THost>, Tag<TTag> const >::Type(me, 0);
 }
-template <typename TValue, unsigned DIMENSION, typename TTag>
-inline typename Iterator<Matrix <TValue, DIMENSION> const, Tag<TTag> const>::Type
-begin(Matrix<TValue, DIMENSION> const & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TTag>
+inline typename Iterator<Matrix <TValue, DIMENSION, THost> const, Tag<TTag> const>::Type
+begin(Matrix<TValue, DIMENSION, THost> const & me,
       Tag<TTag> const)
 {
-    return typename Iterator<Matrix <TValue, DIMENSION> const, Tag<TTag> const >::Type(me, 0);
+    return typename Iterator<Matrix <TValue, DIMENSION, THost> const, Tag<TTag> const >::Type(me, 0);
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TTag>
-inline typename Iterator<Matrix <TValue, DIMENSION>, Tag<TTag> const >::Type
-end(Matrix<TValue, DIMENSION> & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TTag>
+inline typename Iterator<Matrix <TValue, DIMENSION, THost>, Tag<TTag> const >::Type
+end(Matrix<TValue, DIMENSION, THost> & me,
       Tag<TTag> const)
 {
-    return typename Iterator<Matrix <TValue, DIMENSION>, Tag<TTag> const >::Type(me, length(host(me)));
+    return typename Iterator<Matrix <TValue, DIMENSION, THost>, Tag<TTag> const >::Type(me, length(host(me)));
 }
-template <typename TValue, unsigned DIMENSION, typename TTag>
-inline typename Iterator<Matrix <TValue, DIMENSION> const, Tag<TTag> const >::Type
-end(Matrix<TValue, DIMENSION> const & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TTag>
+inline typename Iterator<Matrix <TValue, DIMENSION, THost> const, Tag<TTag> const >::Type
+end(Matrix<TValue, DIMENSION, THost> const & me,
       Tag<TTag> const)
 {
-    return typename Iterator<Matrix <TValue, DIMENSION>, Tag<TTag> const >::Type(me, length(host(me)));
+    return typename Iterator<Matrix <TValue, DIMENSION, THost>, Tag<TTag> const >::Type(me, length(host(me)));
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TPosition>
-inline typename Reference<Matrix<TValue, DIMENSION> >::Type
-value(Matrix<TValue, DIMENSION> & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition>
+inline typename Reference<Matrix<TValue, DIMENSION, THost> >::Type
+value(Matrix<TValue, DIMENSION, THost> & me,
       TPosition position_)
 {
     return value(host(me), position_);
 }
 
-template <typename TValue, unsigned DIMENSION, typename TPosition>
-inline typename Reference<Matrix<TValue, DIMENSION> const>::Type
-value(Matrix<TValue, DIMENSION> const & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition>
+inline typename Reference<Matrix<TValue, DIMENSION, THost> const>::Type
+value(Matrix<TValue, DIMENSION, THost> const & me,
       TPosition position_)
 {
     return value(host(me), position_);
@@ -615,18 +610,18 @@ value(Matrix<TValue, DIMENSION> const & me,
 //____________________________________________________________________________
 
 //two dimensional value access
-template <typename TValue, unsigned DIMENSION, typename TOrdinate1, typename TOrdinate2>
-inline typename Reference<Matrix<TValue, DIMENSION> >::Type
-value(Matrix<TValue, DIMENSION> & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TOrdinate1, typename TOrdinate2>
+inline typename Reference<Matrix<TValue, DIMENSION, THost> >::Type
+value(Matrix<TValue, DIMENSION, THost> & me,
       TOrdinate1 i1,
       TOrdinate2 i2)
 {
     return value(host(me), i1 + i2 * _dataFactors(me)[1]);
 }
 
-template <typename TValue, unsigned DIMENSION, typename TOrdinate1, typename TOrdinate2>
-inline typename Reference<Matrix<TValue, DIMENSION> const>::Type
-value(Matrix<TValue, DIMENSION> const & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TOrdinate1, typename TOrdinate2>
+inline typename Reference<Matrix<TValue, DIMENSION, THost> const>::Type
+value(Matrix<TValue, DIMENSION, THost> const & me,
       TOrdinate1 i1,
       TOrdinate2 i2)
 {
@@ -637,9 +632,9 @@ value(Matrix<TValue, DIMENSION> const & me,
 
 //3 dimensional value access
 
-template <typename TValue, unsigned DIMENSION, typename TOrdinate1, typename TOrdinate2, typename TOrdinate3>
-inline typename Reference<Matrix<TValue, DIMENSION> >::Type
-value(Matrix<TValue, DIMENSION> & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TOrdinate1, typename TOrdinate2, typename TOrdinate3>
+inline typename Reference<Matrix<TValue, DIMENSION, THost> >::Type
+value(Matrix<TValue, DIMENSION, THost> & me,
       TOrdinate1 i1,
       TOrdinate2 i2,
       TOrdinate3 i3)
@@ -651,9 +646,9 @@ value(Matrix<TValue, DIMENSION> & me,
 
 //4 dimensional value access
 
-template <typename TValue, unsigned DIMENSION, typename TOrdinate1, typename TOrdinate2, typename TOrdinate3, typename TOrdinate4>
-inline typename Reference<Matrix<TValue, DIMENSION> >::Type
-value(Matrix<TValue, DIMENSION> & me,
+template <typename TValue, unsigned DIMENSION, typename THost, typename TOrdinate1, typename TOrdinate2, typename TOrdinate3, typename TOrdinate4>
+inline typename Reference<Matrix<TValue, DIMENSION, THost> >::Type
+value(Matrix<TValue, DIMENSION, THost> & me,
       TOrdinate1 i1,
       TOrdinate2 i2,
       TOrdinate3 i3,
@@ -667,32 +662,32 @@ value(Matrix<TValue, DIMENSION> & me,
 // Iterator: goNext
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-goNext(Iter<Matrix<TValue, DIMENSION>, PositionIterator> & me,
+goNext(Iter<Matrix<TValue, DIMENSION, THost>, PositionIterator> & me,
        unsigned int dimension_)
 {
     setPosition(me, nextPosition(container(me), position(me), dimension_));
 }
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-goNext(Iter<Matrix<TValue, DIMENSION> const, PositionIterator> & me,
+goNext(Iter<Matrix<TValue, DIMENSION, THost> const, PositionIterator> & me,
        unsigned int dimension_)
 {
     setPosition(me, nextPosition(container(me), position(me), dimension_));
 }
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-goNext(Iter<Matrix<TValue, DIMENSION>, PositionIterator> & me)
+goNext(Iter<Matrix<TValue, DIMENSION, THost>, PositionIterator> & me)
 {
     goNext(me, 0);
 }
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-goNext(Iter<Matrix<TValue, DIMENSION> const, PositionIterator> & me)
+goNext(Iter<Matrix<TValue, DIMENSION, THost> const, PositionIterator> & me)
 {
     goNext(me, 0);
 }
@@ -701,32 +696,32 @@ goNext(Iter<Matrix<TValue, DIMENSION> const, PositionIterator> & me)
 // Iterator: goPrevious
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-goPrevious(Iter< Matrix<TValue, DIMENSION>, PositionIterator > & me,
+goPrevious(Iter< Matrix<TValue, DIMENSION, THost>, PositionIterator > & me,
            unsigned int dimension_)
 {
     setPosition(me, previousPosition(container(me), position(me), dimension_));
 }
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-goPrevious(Iter< Matrix<TValue, DIMENSION> const, PositionIterator > & me,
+goPrevious(Iter< Matrix<TValue, DIMENSION, THost> const, PositionIterator > & me,
            unsigned int dimension_)
 {
     setPosition(me, previousPosition(container(me), position(me), dimension_));
 }
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-goPrevious(Iter< Matrix<TValue, DIMENSION>, PositionIterator > & me)
+goPrevious(Iter< Matrix<TValue, DIMENSION, THost>, PositionIterator > & me)
 {
     goPrevious(me, 0);
 }
 
-template <typename TValue, unsigned DIMENSION>
+template <typename TValue, unsigned DIMENSION, typename THost>
 inline void
-goPrevious(Iter< Matrix<TValue, DIMENSION> const, PositionIterator > & me)
+goPrevious(Iter< Matrix<TValue, DIMENSION, THost> const, PositionIterator > & me)
 {
     goPrevious(me, 0);
 }
@@ -735,33 +730,33 @@ goPrevious(Iter< Matrix<TValue, DIMENSION> const, PositionIterator > & me)
 // goTo
 //////////////////////////////////////////////////////////////////////////////
 
-template <typename TValue, unsigned DIMENSION, typename TPosition0, typename TPosition1>
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition0, typename TPosition1>
 inline void
-goTo(Iter<Matrix<TValue, DIMENSION>, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1)
+goTo(Iter<Matrix<TValue, DIMENSION, THost>, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1)
 {
     setPosition(me, pos0 + pos1 * _dataFactors(container(me))[1]);
 }
 
 
-template <typename TValue, unsigned DIMENSION, typename TPosition0, typename TPosition1>
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition0, typename TPosition1>
 inline void
-goTo(Iter<Matrix<TValue, DIMENSION> const, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1)
+goTo(Iter<Matrix<TValue, DIMENSION, THost> const, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1)
 {
     setPosition(me, pos0 + pos1 * _dataFactors(container(me))[1]);
 }
 
 
-template <typename TValue, unsigned DIMENSION, typename TPosition0, typename TPosition1, typename TPosition2>
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition0, typename TPosition1, typename TPosition2>
 inline void
-goTo(Iter<Matrix<TValue, DIMENSION>, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1, TPosition2 pos2)
+goTo(Iter<Matrix<TValue, DIMENSION, THost>, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1, TPosition2 pos2)
 {
     setPosition(me, pos0 + pos1 * _dataFactors(container(me))[1] + pos2 * _dataFactors(container(me))[2]);
 }
 
 
-template <typename TValue, unsigned DIMENSION, typename TPosition0, typename TPosition1, typename TPosition2>
+template <typename TValue, unsigned DIMENSION, typename THost, typename TPosition0, typename TPosition1, typename TPosition2>
 inline void
-goTo(Iter<Matrix<TValue, DIMENSION> const, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1, TPosition2 pos2)
+goTo(Iter<Matrix<TValue, DIMENSION, THost> const, PositionIterator> & me, TPosition0 pos0, TPosition1 pos1, TPosition2 pos2)
 {
     setPosition(me, pos0 + pos1 * _dataFactors(container(me))[1] + pos2 * _dataFactors(container(me))[2]);
 }
@@ -769,17 +764,17 @@ goTo(Iter<Matrix<TValue, DIMENSION> const, PositionIterator> & me, TPosition0 po
 //////////////////////////////////////////////////////////////////////////////
 // Iterator: coordinate
 
-template <typename TValue, unsigned DIMENSION>
-inline typename Size< Matrix<TValue, DIMENSION> >::Type
-coordinate(Iter<Matrix<TValue, DIMENSION>, PositionIterator > & me,
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename Size< Matrix<TValue, DIMENSION, THost> >::Type
+coordinate(Iter<Matrix<TValue, DIMENSION, THost>, PositionIterator > & me,
            unsigned int dimension_)
 {
     return coordinate(container(me), position(me), dimension_);
 }
 
-template <typename TValue, unsigned DIMENSION>
-inline typename Size< Matrix<TValue, DIMENSION> >::Type
-coordinate(Iter<Matrix<TValue, DIMENSION> const, PositionIterator > & me,
+template <typename TValue, unsigned DIMENSION, typename THost>
+inline typename Size< Matrix<TValue, DIMENSION, THost> >::Type
+coordinate(Iter<Matrix<TValue, DIMENSION, THost> const, PositionIterator > & me,
            unsigned int dimension_)
 {
     return coordinate(container(me), position(me), dimension_);
@@ -797,9 +792,9 @@ coordinate(Iter<Matrix<TValue, DIMENSION> const, PositionIterator > & me,
  * @return TMatrix The resulting matrix of same type as <tt>lhs</tt> and <tt>rhs</tt>.
  */
 
-template <typename TValue,unsigned DIMENSION>
+template <typename TValue,unsigned DIMENSION, typename THost1, typename THost2>
 Matrix<TValue,DIMENSION>
-operator + (Matrix<TValue,DIMENSION> const & matrix1,Matrix<TValue,DIMENSION> const & matrix2)
+operator + (Matrix<TValue,DIMENSION, THost1> const & matrix1, Matrix<TValue,DIMENSION, THost2> const & matrix2)
 {
     //the two matrices must have same dimension
     SEQAN_ASSERT(_dataLengths(matrix1) == _dataLengths(matrix2));
@@ -819,9 +814,9 @@ operator + (Matrix<TValue,DIMENSION> const & matrix1,Matrix<TValue,DIMENSION> co
     return result;
 }
 
-template <typename TValue,unsigned DIMENSION>
+template <typename TValue,unsigned DIMENSION, typename THost1, typename THost2>
 Matrix<TValue,DIMENSION>
-operator - (Matrix<TValue,DIMENSION> const & matrix1,Matrix<TValue,DIMENSION> const & matrix2)
+operator - (Matrix<TValue,DIMENSION, THost1> const & matrix1,Matrix<TValue,DIMENSION, THost2> const & matrix2)
 {
     //the two matrices must have same dimension
     SEQAN_ASSERT(_dataLengths(matrix1) == _dataLengths(matrix2));
@@ -841,9 +836,9 @@ operator - (Matrix<TValue,DIMENSION> const & matrix1,Matrix<TValue,DIMENSION> co
     return result;
 }
 
-template <typename TValue>
+template <typename TValue, typename THost1, typename THost2>
 Matrix<TValue, 2>
-operator * (Matrix<TValue, 2> const & matrix1, Matrix<TValue, 2> const & matrix2)
+operator * (Matrix<TValue, 2, THost1> const & matrix1, Matrix<TValue, 2, THost2> const & matrix2)
 {
     SEQAN_ASSERT_EQ(length(matrix1,1), length(matrix2,0));
 
@@ -871,9 +866,9 @@ operator * (Matrix<TValue, 2> const & matrix1, Matrix<TValue, 2> const & matrix2
 }
 
 
-template <typename TValue>
+template <typename TValue, typename THost>
 Matrix<TValue, 2>
-operator * (TValue const & scalar, Matrix<TValue, 2> const & matrix)
+operator * (TValue const & scalar, Matrix<TValue, 2, THost> const & matrix)
 {
     Matrix<TValue, 2> result;
     result= matrix;
@@ -886,9 +881,9 @@ operator * (TValue const & scalar, Matrix<TValue, 2> const & matrix)
     return result;
 }
 
-template <typename TValue>
+template <typename TValue, typename THost>
 Matrix<TValue, 2>
-operator * (Matrix<TValue, 2> const & matrix, TValue const & scalar)
+operator * (Matrix<TValue, 2, THost> const & matrix, TValue const & scalar)
 {
     Matrix<TValue, 2> result;
     result= matrix;
@@ -902,9 +897,9 @@ operator * (Matrix<TValue, 2> const & matrix, TValue const & scalar)
 }
 
 
-template <typename TValue, unsigned DIMENSION1, unsigned DIMENSION2>
+template <typename TValue, unsigned DIMENSION1, typename THost1, unsigned DIMENSION2, typename THost2>
 bool
-operator == (Matrix<TValue, DIMENSION1> const & matrix1, Matrix<TValue, DIMENSION2> const & matrix2)
+operator == (Matrix<TValue, DIMENSION1, THost1> const & matrix1, Matrix<TValue, DIMENSION2, THost2> const & matrix2)
 {
     bool result;
     result= (matrix1.data_lengths==matrix2.data_lengths)&&(matrix1.data_factors==matrix2.data_factors)&&(value(matrix1.data_host)==value(matrix2.data_host))&&(DIMENSION1==DIMENSION2);
@@ -1027,9 +1022,9 @@ matricialProduct(Matrix<TValue, 2> &matrix1,
  * @return TMatrix The resulting tranposed matrix.
  */
 
-template <typename TValue>
+template <typename TValue, typename THost>
 Matrix<TValue,2>
-transpose(Matrix<TValue,2> const & matrix)
+transpose(Matrix<TValue,2, THost> const & matrix)
 {
 
     unsigned int nrow=length(matrix,0);
@@ -1057,8 +1052,8 @@ transpose(Matrix<TValue,2> const & matrix)
 }
 
 
-template < typename TValue >
-std::ostream& operator<<(std::ostream &out, const Matrix<TValue,2> &matrix)
+template < typename TValue , typename THost>
+std::ostream& operator<<(std::ostream &out, const Matrix<TValue,2, THost> &matrix)
 {
     for(unsigned int i1 = 0;i1< matrix.data_lengths[0];++i1)
     {
diff --git a/include/seqan/align_extend/align_extend.h b/include/seqan/align_extend/align_extend.h
index 6489927..6a1cd58 100644
--- a/include/seqan/align_extend/align_extend.h
+++ b/include/seqan/align_extend/align_extend.h
@@ -416,7 +416,7 @@ _extendAlignmentImpl(Align<TStringInfix, TAlignSpec> & align,
 {
     if (scoreGapOpen(scoreScheme) == scoreGapExtend(scoreScheme))
     {
-        typedef DPContext<TScoreValue, LinearGaps> TDPContext;
+        typedef DPContext<DPCell_<TScoreValue, LinearGaps>, typename TraceBitMap_<TScoreValue>::Type> TDPContext;
         typedef AliExtContext_<Gaps<TStringInfix, TAlignSpec>,
                                Gaps<TStringInfix, TAlignSpec>,
                                TDPContext> TAliExtContext_;
@@ -426,7 +426,7 @@ _extendAlignmentImpl(Align<TStringInfix, TAlignSpec> & align,
     }
     else
     {
-        typedef DPContext<TScoreValue, AffineGaps> TDPContext;
+        typedef DPContext<DPCell_<TScoreValue, AffineGaps>, typename TraceBitMap_<TScoreValue>::Type> TDPContext;
         typedef AliExtContext_<Gaps<TStringInfix, TAlignSpec>,
                                Gaps<TStringInfix, TAlignSpec>,
                                TDPContext> TAliExtContext_;
diff --git a/include/seqan/align_extend/align_extend_base.h b/include/seqan/align_extend/align_extend_base.h
index 336daed..80f33cd 100644
--- a/include/seqan/align_extend/align_extend_base.h
+++ b/include/seqan/align_extend/align_extend_base.h
@@ -86,10 +86,10 @@ struct IsFreeEndGap_<AlignExtend_<TSpec>, DPLastColumn> : True
 // Class DPMetaColumn_                                             [FullColumn]
 // ----------------------------------------------------------------------------
 
-template <typename TSpec, typename TGapCosts, typename TTraceback,
+template <typename TSpec, typename TGapCosts, typename TTraceback, typename TExecPolicy,
           typename TColumnType>
 struct DPMetaColumn_<DPProfile_<AlignExtend_<TSpec>, TGapCosts,
-                                TTraceback>,
+                                TTraceback, TExecPolicy>,
                      MetaColumnDescriptor<TColumnType, FullColumn> >
 {
 
@@ -116,10 +116,10 @@ struct DPMetaColumn_<DPProfile_<AlignExtend_<TSpec>, TGapCosts,
 // Class DPMetaColumn_                                       [PartialColumnTop]
 // ----------------------------------------------------------------------------
 
-template <typename TSpec, typename TGapCosts, typename TTraceback,
+template <typename TSpec, typename TGapCosts, typename TTraceback, typename TExecPolicy,
           typename TColumnType>
 struct DPMetaColumn_<DPProfile_<AlignExtend_<TSpec>, TGapCosts,
-                                TTraceback>,
+                                TTraceback, TExecPolicy>,
                      MetaColumnDescriptor<TColumnType, PartialColumnTop> >
 {
 
@@ -145,10 +145,10 @@ struct DPMetaColumn_<DPProfile_<AlignExtend_<TSpec>, TGapCosts,
 // Class DPMetaColumn_                                    [PartialColumnMiddle]
 // ----------------------------------------------------------------------------
 
-template <typename TSpec, typename TGapCosts, typename TTraceback,
+template <typename TSpec, typename TGapCosts, typename TTraceback, typename TExecPolicy,
           typename TColumnType>
 struct DPMetaColumn_<DPProfile_<AlignExtend_<TSpec>, TGapCosts,
-                                TTraceback>,
+                                TTraceback, TExecPolicy>,
                      MetaColumnDescriptor<TColumnType, PartialColumnMiddle> >
 {
     typedef typename If<IsSameType<TColumnType,
@@ -173,10 +173,10 @@ struct DPMetaColumn_<DPProfile_<AlignExtend_<TSpec>, TGapCosts,
 // Class DPMetaColumn_                                    [PartialColumnBottom]
 // ----------------------------------------------------------------------------
 
-template <typename TSpec, typename TGapCosts, typename TTraceback,
+template <typename TSpec, typename TGapCosts, typename TTraceback, typename TExecPolicy,
           typename TColumnType>
 struct DPMetaColumn_<DPProfile_<AlignExtend_<TSpec>, TGapCosts,
-                                TTraceback>,
+                                TTraceback, TExecPolicy>,
                      MetaColumnDescriptor<TColumnType, PartialColumnBottom> >
 {
     typedef typename If<IsSameType<TColumnType,
diff --git a/include/seqan/align_extend/dp_scout_xdrop.h b/include/seqan/align_extend/dp_scout_xdrop.h
index 9cd22eb..01023ea 100644
--- a/include/seqan/align_extend/dp_scout_xdrop.h
+++ b/include/seqan/align_extend/dp_scout_xdrop.h
@@ -131,7 +131,7 @@ _scoutBestScore(DPScout_<TDPCell, Terminator_<XDrop_<TDPCellValue> > > & dpScout
     typedef typename Value<TDPCell>::Type TScoreValue;
     typedef XDrop_<TScoreValue> TXDrop;
     typedef DPScout_<TDPCell, Terminator_<TXDrop> > TDPScout;
-    typedef typename TDPScout::TParent TParent;
+    typedef typename TDPScout::TBase TParent;
 
     // global maximum
     _scoutBestScore(static_cast<TParent &>( dpScout ), activeCell, navigator);
@@ -164,16 +164,18 @@ _scoutBestScore(DPScout_<TDPCell, Terminator_<XDrop_<TDPCellValue> > > & dpScout
 // ----------------------------------------------------------------------------
 
 // Computes the score and tracks it if enabled.
-template <typename TDPScout, typename TTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
+template <typename TDPScout, typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TScoreValue, typename TGapCosts,
           typename TSequenceHValue, typename TSequenceVValue, typename TScoringScheme, typename TColumnDescriptor,
           typename TCellDescriptor, typename TTraceback>
 inline void
 _computeCell(TDPScout & scout,
              TTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const & previousDiagonal,
-             DPCell_<TScoreValue, TGapCosts> const & previousHorizontal,
-             DPCell_<TScoreValue, TGapCosts> const & previousVertical,
+             TDPCell & current,
+             TDPCell & diagonal,
+             TDPCell const & horizontal,
+             TDPCell & vertical,
              TSequenceHValue const & seqHVal,
              TSequenceVValue const & seqVVal,
              TScoringScheme const & scoringScheme,
@@ -185,7 +187,7 @@ _computeCell(TDPScout & scout,
     typedef DPProfile_<AlignExtend_<XDrop_<TScoreValue> >, TGapCosts, TTraceback> TDPProfile;
     typedef DPMetaColumn_<TDPProfile, TColumnDescriptor> TMetaColumn;
 
-    assignValue(traceMatrixNavigator, _computeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical,
+    assignValue(traceMatrixNavigator, _computeScore(current, diagonal, horizontal, vertical,
                                                     seqHVal, seqVVal, scoringScheme,
                                                     typename RecursionDirection_<TMetaColumn, TCellDescriptor>::Type(),
                                                     TDPProfile()));
@@ -196,8 +198,9 @@ _computeCell(TDPScout & scout,
         // the following is the only change to the regular _computeCell:
         // for the evaluation of the termination criterium we treat
         // all lastCells as lastRows
+        _setVerticalScoreOfCell(current, _verticalScoreOfCell(vertical));
         typedef typename IsSameType<TCellDescriptor, LastCell>::Type TIsLastRow;
-        _scoutBestScore(scout, activeCell, traceMatrixNavigator, TIsLastColumn(), TIsLastRow());
+        _scoutBestScore(scout, current, traceMatrixNavigator, TIsLastColumn(), TIsLastRow());
     }
 }
 
diff --git a/include/seqan/parallel/parallel_tags.h b/include/seqan/align_parallel.h
similarity index 54%
copy from include/seqan/parallel/parallel_tags.h
copy to include/seqan/align_parallel.h
index 20d395c..149fd02 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/include/seqan/align_parallel.h
@@ -29,58 +29,74 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tags to select serial/parallel algorithms.
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
-#define SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_H_
+
+// ============================================================================
+// STD Prerequisites
+// ============================================================================
+
+#if SEQAN_DEBUG_ENABLED
+#include <typeinfo>
+#include <cxxabi.h>
+#include <stdlib.h>
+#endif
 
-namespace seqan {
+#include <type_traits>
+#include <utility>
+#include <vector>
 
 // ============================================================================
-// Forwards
+// SeqAn Prerequisites
 // ============================================================================
 
+#include <seqan/basic.h>
+#include <seqan/simd.h>
+#include <seqan/align.h>
+#include <seqan/parallel.h>
+
 // ============================================================================
-// Tags, Classes, Enums
+// Parallel DP Prerequisites and Adaptors
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Tag Parallel
-// ----------------------------------------------------------------------------
+#include <seqan/align_parallel/dp_parallel_execution_policies.h>
+#include <seqan/align_parallel/dp_traits.h>
+#include <seqan/align_parallel/dp_kernel_adaptor.h>
+#include <seqan/align_parallel/dp_settings.h>
+#include <seqan/align_parallel/dp_parallel_scout.h>
+#ifdef SEQAN_SIMD_ENABLED
+#include <seqan/align_parallel/dp_parallel_scout_simd.h>
+#endif
 
-/*!
- * @defgroup ParallelismTags Parallelism Tags
- * @brief Tags for enabling/disabling parallelism.
- *
- * @tag ParallelismTags#Parallel
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the parallel implementation of an algorithm.
- *
- * @tag ParallelismTags#Serial
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the serial implementation of an algorithm.
- */
+// ============================================================================
+// Wavefront  Task
+// ============================================================================
 
-struct Parallel_;
-typedef Tag<Parallel_> Parallel;
+#include <seqan/align_parallel/wavefront_task_scheduler.h>
+#include <seqan/align_parallel/wavefront_task_queue.h>
+#include <seqan/align_parallel/wavefront_task_event.h>
+#include <seqan/align_parallel/wavefront_task_util.h>
+#include <seqan/align_parallel/wavefront_task.h>
+#include <seqan/align_parallel/wavefront_task_executor.h>
 
 // ============================================================================
-// Metafunctions
+// Wavefront Alignment Tasks
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Metafunction DefaultParallelSpec
-// ----------------------------------------------------------------------------
+#include <seqan/align_parallel/wavefront_alignment_scheduler.h>
+#include <seqan/align_parallel/wavefront_alignment_result.h>     // TODO(rrahn): rename! refactor!
+#include <seqan/align_parallel/wavefront_alignment_thread_local_storage.h>
+#include <seqan/align_parallel/wavefront_alignment_executor.h>
+#include <seqan/align_parallel/wavefront_alignment_task.h>
 
-template <typename TObject>
-struct DefaultParallelSpec
-{
-    typedef Parallel Type;
-};
+// ============================================================================
+// Interfaces
+// ============================================================================
 
-}  // namespace seqan
+#include <seqan/align_parallel/async_wave_execution_interface.h>
+#include <seqan/align_parallel/parallel_align_interface.h>
 
-#endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_H_
diff --git a/include/seqan/align_parallel/async_wave_execution_interface.h b/include/seqan/align_parallel/async_wave_execution_interface.h
new file mode 100644
index 0000000..eb36a90
--- /dev/null
+++ b/include/seqan/align_parallel/async_wave_execution_interface.h
@@ -0,0 +1,252 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_ASYNC_WAVE_EXECUTION_INTERFACE_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_ASYNC_WAVE_EXECUTION_INTERFACE_H_
+
+namespace seqan
+{
+namespace impl
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+/*
+ * @class AsyncWaveAlignExecutor
+ * @brief Executor of the wave-front alignment mode with no SIMD vectorization.
+ * @headerfile <seqan/align_parallel.h>
+ *
+ * Manges shared data for the wave-front execution before executing the alignments.
+ */
+template <typename TSeqH, typename TSeqV, typename TSettings>
+class AsyncWaveAlignExecutor
+{
+public:
+
+    using TAlignmentTask = WavefrontAlignmentTask<TSeqH, TSeqV, TSettings>;
+    using TThreadLocal   = typename WavefrontAlignmentTaskConfig<TSettings>::TThreadLocal;
+    using TStorage       = EnumerableThreadLocal<TThreadLocal, CountingThreadLocalManager>;
+    using TExecutor      = WavefrontAlignmentExecutor<WavefrontTaskScheduler, TStorage>;
+
+    TSettings                                   _settings;
+    // Initialize the alignment scheduler.
+    WavefrontAlignmentScheduler                 _alignScheduler;
+
+    TStorage                                    _threadLocalStorage{};
+    TExecutor                                   _executor{};
+    unsigned                                    _alignCounter{0};
+    unsigned                                    _blockSize{};
+
+    template <typename TSpec>
+    AsyncWaveAlignExecutor(TSettings settings,
+                           ExecutionPolicy<WavefrontAlignment<TSpec>, Serial> const & execPolicy) :
+        _settings(std::move(settings)),
+        _alignScheduler(parallelAlignments(execPolicy), numThreads(execPolicy)),
+        _threadLocalStorage(TThreadLocal{parallelAlignments(execPolicy)}),
+        _blockSize(blockSize(execPolicy))
+    {
+        _executor.ptrTaskScheduler = &taskScheduler(_alignScheduler);
+        _executor.ptrThreadLocal   = &_threadLocalStorage;
+        setCount(storageManager(_threadLocalStorage), numThreads(execPolicy));
+    }
+};
+
+/*
+ * @fn AsyncWaveAlignExecutor#submit
+ * @brief Submits a new alignment job asynchronosly.
+ */
+template <typename ...TArgs,
+          typename TSeqH,
+          typename TSeqV,
+          typename TCallable>
+inline void
+submit(AsyncWaveAlignExecutor<TArgs...> & me,
+       TSeqH const & seqH,
+       TSeqV const & seqV,
+       TCallable && callback)
+{
+    using TAlignTask = typename AsyncWaveAlignExecutor<TArgs...>::TAlignmentTask;
+
+    std::function<void(uint16_t)> f =
+        [&, func = TAlignTask{me._alignCounter++, seqH, seqV, me._settings, me._blockSize}](uint16_t id) mutable
+        {
+            func(id, me._executor, std::forward<TCallable>(callback));
+        };
+    scheduleTask(me._alignScheduler, f);
+}
+
+/*
+ * @fn AsyncWaveAlignExecutor#wait
+ * @brief Explicit barrier to wait for all submitted jobs to be finished.
+ */
+template <typename ...TArgs>
+inline void
+wait(AsyncWaveAlignExecutor<TArgs...> & me)
+{
+    notify(me._alignScheduler);
+    wait(me._alignScheduler);
+}
+
+/*
+ * @class AsyncWaveAlignExecutorSimd
+ * @brief Executor of the wave-front alignment mode with SIMD vectorization.
+ * @headerfile <seqan/align_parallel.h>
+ *
+ * Manges shared data for the wave-front execution before executing the alignments.
+ */
+#ifdef SEQAN_SIMD_ENABLED
+template <typename TSeqH, typename TSeqV, typename TSettings, typename TWaveSpec>
+class AsyncWaveAlignExecutorSimd
+{
+public:
+
+    // Translate dp settings into simd settings.
+    using TSimdSettings = SimdDPSettings<TSettings, TWaveSpec>;
+
+    using TAlignmentTask = WavefrontAlignmentTask<TSeqH, TSeqV, TSimdSettings,
+                                                  WavefrontAlignmentSimdTaskConfig<TSimdSettings>>;
+    using TWavefrontTask = WavefrontTask<typename TAlignmentTask::TTaskContext>;
+    using TSimdTaskQueue = WavefrontTaskQueue<TWavefrontTask, LENGTH<typename TSimdSettings::TScoreValueSimd>::VALUE>;
+
+    using TThreadLocal  = typename WavefrontAlignmentSimdTaskConfig<TSimdSettings>::TThreadLocal;
+    using TStorage      = EnumerableThreadLocal<TThreadLocal, CountingThreadLocalManager>;
+    using TExecutor     = WavefrontAlignmentExecutor<WavefrontTaskScheduler, TStorage>;
+
+
+    TSimdSettings                               _settings;
+    // Initialize the alignment scheduler.
+    WavefrontAlignmentScheduler                 _alignScheduler;
+
+    TStorage                                    _threadLocalStorage;
+    TExecutor                                   _executor{};
+    TSimdTaskQueue                              _simdTaskQueue{};
+    unsigned                                    _alignCounter{0};
+    unsigned                                    _blockSize{};
+
+    template <typename TSpec>
+    AsyncWaveAlignExecutorSimd(TSettings const & settings,
+                               ExecutionPolicy<WavefrontAlignment<TSpec>, Vectorial> const & execPolicy) :
+        _settings(settings.scoringScheme),
+        _alignScheduler(parallelAlignments(execPolicy), numThreads(execPolicy)),
+        _threadLocalStorage(TThreadLocal{parallelAlignments(execPolicy)}),
+        _blockSize(blockSize(execPolicy))
+    {
+        _executor.ptrTaskScheduler = &taskScheduler(_alignScheduler);
+        _executor.ptrThreadLocal   = &_threadLocalStorage;
+        setCount(storageManager(_threadLocalStorage), numThreads(execPolicy));
+    }
+};
+
+/*
+ * @fn AsyncWaveAlignExecutorSimd#submit
+ * @brief Submits a new alignment job asynchronosly.
+ */
+template <typename ...TArgs,
+          typename TSeqH,
+          typename TSeqV,
+          typename TCallable>
+inline void
+submit(AsyncWaveAlignExecutorSimd<TArgs...> & me,
+       TSeqH const & seqH,
+       TSeqV const & seqV,
+       TCallable && callback)
+{
+    using TAlignTask = typename AsyncWaveAlignExecutorSimd<TArgs...>::TAlignmentTask;
+
+    // Continuator for calling the alignment instance functor.
+    std::function<void(uint16_t)> f =
+        [&, func = TAlignTask{me._alignCounter++, seqH, seqV, me._settings, me._blockSize}](uint16_t id) mutable
+        {
+            func(id, me._executor, me._simdTaskQueue, std::forward<TCallable>(callback));
+        };
+    scheduleTask(me._alignScheduler, f);
+}
+
+/*
+ * @fn AsyncWaveAlignExecutorSimd#wait
+ * @brief Explicit barrier to wait for all submitted jobs to be finished.
+ */
+template <typename ...TArgs>
+inline void
+wait(AsyncWaveAlignExecutorSimd<TArgs...> & me)
+{
+    notify(me._alignScheduler);
+    wait2(me._alignScheduler, me._simdTaskQueue);
+}
+#endif // SEQAN_SIMD_ENABLED
+
+/*
+ * @fn alignExecBatch
+ * @brief Global interface for scheduling and running all alignment jobs with wave-front model.
+ */
+template <typename TSpec, typename TSimdSpec,
+          typename TSetH,
+          typename TSetV,
+          typename TSettings,
+          typename TCallable>
+inline void
+alignExecBatch(ExecutionPolicy<WavefrontAlignment<TSpec>, TSimdSpec> const & execPolicy,
+               TSetH const & setH,
+               TSetV const & setV,
+               TSettings const & settings,
+               TCallable && callback)
+{
+    using TSeqH = typename Value<TSetH const>::Type;
+    using TSeqV = typename Value<TSetV const>::Type;
+
+#ifdef SEQAN_SIMD_ENABLED
+    using TExecutor = std::conditional_t<std::is_same<TSimdSpec, Vectorial>::value,
+                                         AsyncWaveAlignExecutorSimd<TSeqH, TSeqV, TSettings, TSpec>,
+                                         AsyncWaveAlignExecutor<TSeqH, TSeqV, TSettings>>;
+#else
+    using TExecutor = AsyncWaveAlignExecutor<TSeqH, TSeqV, TSettings>;
+#endif
+    TExecutor executor(settings, execPolicy);
+
+    for (size_t i = 0u; i < length(setH); ++i)
+    {
+        submit(executor, setH[i], setV[i], std::forward<TCallable>(callback));
+    }
+    wait(executor);
+}
+
+}  // namespace impl
+}  // namespace seqan
+#endif  // INCLUDE_SEQAN_ALIGN_PARALLEL_ASYNC_WAVE_EXECUTION_INTERFACE_H_
diff --git a/include/seqan/align_parallel/dp_kernel_adaptor.h b/include/seqan/align_parallel/dp_kernel_adaptor.h
new file mode 100644
index 0000000..7dd64e8
--- /dev/null
+++ b/include/seqan/align_parallel/dp_kernel_adaptor.h
@@ -0,0 +1,343 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_KERNEL_ADAPTOR_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_KERNEL_ADAPTOR_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template <typename TCond1, typename TCond2>
+struct CorrectLastColumn_ : False
+{};
+
+template <>
+struct CorrectLastColumn_<True, True> : True
+{};
+
+template <typename TCond1, typename TCond2>
+struct CorrectLastRow_ : False
+{};
+
+template <>
+struct CorrectLastRow_<True, True> : True
+{};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Function _computeCell(); InitialCol;
+// ----------------------------------------------------------------------------
+
+// The _computeCell function is the basic interface that is called to comute
+// the score for each cell and to store the corresponding traceback.
+// The MetaColumnDescriptor and the CellDescriptor describe which cell in the dp matrix
+// is computed. We use this information to overload the functions in order
+// to initialize from the passed buffer and to store the last row/column in the buffer.
+
+// Vertical initialization values are copied from buffer.
+template <typename TDPScout,
+          typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TCellDescriptor,
+          typename TAlgo, typename TGapCosts, typename TTraceConfig>
+inline void
+_computeCell(TDPScout & scout,
+             TTraceMatrixNavigator & traceMatrixNavigator,
+             TDPCell & current,
+             TDPCell & /*cacheDiag*/,
+             TDPCell const & /*cacheHori*/,
+             TDPCell & /*cacheVert*/,
+             TSequenceHValue const & /*seqHVal*/,
+             TSequenceVValue const & /*seqVVal*/,
+             TScoringScheme const & /*scoringScheme*/,
+             MetaColumnDescriptor<DPInitialColumn, FullColumn> const &,
+             TCellDescriptor const &,   // One of FirstCell, InnerCell or LastCell.
+             DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel> const &)
+{
+    typedef DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel>                            TDPProfile;
+    typedef DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInitialColumn, FullColumn> >   TMetaColumn;
+
+    current = (*scout.state.ptrVerBuffer)[scout.verticalPos].i1;
+    assignValue(traceMatrixNavigator, (*scout.state.ptrVerBuffer)[scout.verticalPos].i2);
+
+    if (TrackingEnabled_<TMetaColumn, TCellDescriptor>::VALUE)
+    {
+        _scoutBestScore(scout, current, traceMatrixNavigator, False(), False());
+    }
+}
+
+// ----------------------------------------------------------------------------
+// Function _computeCell(); InnerCol; FirstCell
+// ----------------------------------------------------------------------------
+
+// Horizontal initialization values are copied from buffer for all first cells.
+template <typename TDPScout,
+          typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TAlgo, typename TGapCosts, typename TTraceConfig>
+inline void
+_computeCell(TDPScout & scout,
+             TTraceMatrixNavigator & traceMatrixNavigator,
+             TDPCell & current,
+             TDPCell & cacheDiag,
+             TDPCell const & cacheHori,
+             TDPCell & cacheVert,
+             TSequenceHValue const & /*seqHVal*/,
+             TSequenceVValue const & /*seqVVal*/,
+             TScoringScheme const & /*scoringScheme*/,
+             MetaColumnDescriptor<DPInnerColumn, FullColumn> const &,
+             FirstCell const &,   // One of FirstCell, InnerCell or LastCell.
+             DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel> const &)
+{
+    _scoreOfCell(cacheDiag) = _scoreOfCell(cacheHori);
+    current = (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i1;
+    cacheVert = current;
+    assignValue(traceMatrixNavigator, (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i2);
+}
+
+// ----------------------------------------------------------------------------
+// Function _computeCell(); InnerCol; LastCell
+// ----------------------------------------------------------------------------
+
+// Values of last call are copied into the horizontal buffer for initializing next tile below.
+template <typename TDPScout,
+          typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TAlgo, typename TGapCosts, typename TTraceConfig>
+inline void
+_computeCell(TDPScout & scout,
+             TTraceMatrixNavigator & traceMatrixNavigator,
+             TDPCell & current,
+             TDPCell & cacheDiag,
+             TDPCell const & cacheHori,
+             TDPCell & cacheVert,
+             TSequenceHValue const & seqHVal,
+             TSequenceVValue const & seqVVal,
+             TScoringScheme const & scoringScheme,
+             MetaColumnDescriptor<DPInnerColumn, FullColumn> const &,
+             LastCell const & /*cellDescriptor*/,
+             DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel> const &)
+{
+    typedef DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel>                            TDPProfile;
+    typedef DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPInnerColumn, FullColumn> >     TMetaColumn;
+
+    assignValue(traceMatrixNavigator,
+                _computeScore(current, cacheDiag, cacheHori, cacheVert, seqHVal, seqVVal,
+                              scoringScheme, typename RecursionDirection_<TMetaColumn, LastCell>::Type(),
+                              TDPProfile()));
+    // Copy values into horizontal buffer for the tile below this tile in vertical direction.
+    // TODO(rrahn): We need to do this only for affine gaps?
+    _setVerticalScoreOfCell(current, _verticalScoreOfCell(cacheVert));
+    (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i1 = current;
+    if (IsTracebackEnabled_<TTraceConfig>::VALUE)
+    {
+        (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i2 = value(traceMatrixNavigator);
+    }
+
+    if (TrackingEnabled_<TMetaColumn, LastCell>::VALUE)
+    {
+        _scoutBestScore(scout, current, traceMatrixNavigator, False(), True());
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+// Function _computeCell(); FinalCol; FirstCell
+// ----------------------------------------------------------------------------
+
+// Horizontal initialization values are copied from buffer for all first cells.
+// Vertical buffer is filled with value.
+template <typename TDPScout,
+          typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TAlgo, typename TGapCosts, typename TTraceConfig>
+inline void
+_computeCell(TDPScout & scout,
+             TTraceMatrixNavigator & traceMatrixNavigator,
+             TDPCell & current,
+             TDPCell & cacheDiag,
+             TDPCell const & cacheHori,
+             TDPCell & cacheVert,
+             TSequenceHValue const & /*seqHVal*/,
+             TSequenceVValue const & /*seqVVal*/,
+             TScoringScheme const & /*scoringScheme*/,
+             MetaColumnDescriptor<DPFinalColumn, FullColumn> const &,
+             FirstCell const &,   // One of FirstCell, InnerCell or LastCell.
+             DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel> const &)
+{
+    typedef DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel>                            TDPProfile;
+    typedef DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >     TMetaColumn;
+
+    // cache previous diagonal.
+    _scoreOfCell(cacheDiag) = _scoreOfCell(cacheHori);
+    current =
+        front(*scout.state.ptrVerBuffer).i1 = (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i1;  // Copy horizontal buffer value in active cell and in
+    assignValue(traceMatrixNavigator, (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i2);
+    cacheVert = current;
+    if (IsTracebackEnabled_<TTraceConfig>::VALUE)
+    {
+        front(*scout.state.ptrVerBuffer).i2 = value(traceMatrixNavigator);   // Store trace value in vertical buffer.
+    }
+
+    if (TrackingEnabled_<TMetaColumn, FirstCell>::VALUE)
+    {
+        _scoutBestScore(scout, current, traceMatrixNavigator, True(), False());
+    }
+}
+
+// ----------------------------------------------------------------------------
+// Function _computeCell(); FinalCol, InnerCell;
+// ----------------------------------------------------------------------------
+
+// Stores computed values in vertical buffer for initializing next tile right of the current.
+template <typename TDPScout,
+          typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TAlgo, typename TGapCosts, typename TTraceConfig>
+inline void
+_computeCell(TDPScout & scout,
+             TTraceMatrixNavigator & traceMatrixNavigator,
+             TDPCell & current,
+             TDPCell & cacheDiag,
+             TDPCell const & cacheHori,
+             TDPCell & cacheVert,
+             TSequenceHValue const & seqHVal,
+             TSequenceVValue const & seqVVal,
+             TScoringScheme const & scoringScheme,
+             MetaColumnDescriptor<DPFinalColumn, FullColumn> const &,
+             InnerCell const &,
+             DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel> const &)
+{
+    typedef DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel>                            TDPProfile;
+    typedef DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >     TMetaColumn;
+
+    assignValue(traceMatrixNavigator,
+                _computeScore(current, cacheDiag, cacheHori, cacheVert, seqHVal, seqVVal,
+                              scoringScheme, typename RecursionDirection_<TMetaColumn, InnerCell>::Type(),
+                              TDPProfile()));
+    // Store values in vertical buffer.
+    _setVerticalScoreOfCell(current, _verticalScoreOfCell(cacheVert));
+    (*scout.state.ptrVerBuffer)[scout.verticalPos].i1 = current;
+    if (IsTracebackEnabled_<TTraceConfig>::VALUE)
+    {
+        (*scout.state.ptrVerBuffer)[scout.verticalPos].i2 = value(traceMatrixNavigator);
+    }
+
+    if (TrackingEnabled_<TMetaColumn, InnerCell>::VALUE)
+    {
+        _scoutBestScore(scout, current, traceMatrixNavigator, True(), False());
+    }
+}
+
+// ----------------------------------------------------------------------------
+// Function _computeCell(); FinalCol, LastCell;
+// ----------------------------------------------------------------------------
+
+// Stores computed values in vertical buffer for initializing next tile right of the current.
+// Stores computed values in horizontal buffer for initializing next tile below.
+template <typename TDPScout,
+          typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSequenceHValue,
+          typename TSequenceVValue,
+          typename TScoringScheme,
+          typename TAlgo, typename TGapCosts, typename TTraceConfig>
+inline void
+_computeCell(TDPScout & scout,
+             TTraceMatrixNavigator & traceMatrixNavigator,
+             TDPCell & current,
+             TDPCell & cacheDiag,
+             TDPCell const & cacheHori,
+             TDPCell & cacheVert,
+             TSequenceHValue const & seqHVal,
+             TSequenceVValue const & seqVVal,
+             TScoringScheme const & scoringScheme,
+             MetaColumnDescriptor<DPFinalColumn, FullColumn> const &,
+             LastCell const &,
+             DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel> const &)
+{
+    typedef DPProfile_<TAlgo, TGapCosts, TTraceConfig, Parallel>                            TDPProfile;
+    typedef DPMetaColumn_<TDPProfile, MetaColumnDescriptor<DPFinalColumn, FullColumn> >     TMetaColumn;
+
+    assignValue(traceMatrixNavigator,
+                _computeScore(current, cacheDiag, cacheHori, cacheVert, seqHVal, seqVVal,
+                              scoringScheme, typename RecursionDirection_<TMetaColumn, LastCell>::Type(),
+                              TDPProfile()));
+    // Store values in vertical and horizontal buffer
+    _setVerticalScoreOfCell(current, _verticalScoreOfCell(cacheVert));
+    (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i1 = (*scout.state.ptrVerBuffer)[scout.verticalPos].i1 = current;
+    if (IsTracebackEnabled_<TTraceConfig>::VALUE)
+    {
+        (*scout.state.ptrHorBuffer)[scout.horizontalPos - 1].i2 =
+            (*scout.state.ptrVerBuffer)[scout.verticalPos].i2 = value(traceMatrixNavigator);
+    }
+    if (TrackingEnabled_<TMetaColumn, LastCell>::VALUE)
+    {
+        _scoutBestScore(scout, current, traceMatrixNavigator, True(), True());
+    }
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_KERNEL_ADAPTOR_H_
diff --git a/include/seqan/align_parallel/dp_parallel_execution_policies.h b/include/seqan/align_parallel/dp_parallel_execution_policies.h
new file mode 100644
index 0000000..bc528fb
--- /dev/null
+++ b/include/seqan/align_parallel/dp_parallel_execution_policies.h
@@ -0,0 +1,174 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+// Policies used for parallel alignment computation.
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_PARALLEL_EXECUTION_PLOCIES_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_PARALLEL_EXECUTION_PLOCIES_H_
+
+namespace seqan
+{
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+/*!
+ * @tag BlockOffsetOptimization
+ * @brief Optimization for vectorized wave-front execution model.
+ * @headerfile <seqan/align_parallel.h>
+ * @see WavefrontExecutionPolicy
+ */
+struct BlockOffsetOptimization_;
+using BlockOffsetOptimization = Tag<BlockOffsetOptimization_>;
+
+/*!
+ * @class WavefrontExecutionPolicy
+ * @headerfile <seqan/align_parallel.h>
+ * @extends ExecutionPolicy
+ * @brief Policy to select runtime execution mode for algorithms.
+ * @signature template<typename TWaveSpec, typename TVectorizationMode>
+ *            struct ExecutionPolicy<WavefrontAlignment<TWaveSpec>, TVectorizationMode>;
+ * @tparam TWaveSpec Type specializing the wave-front threading model.
+ *         Can be <tt>void</tt> (default) or @link BlockOffsetOptimization @endlink.
+ * @tparam TVectorizationMode Type specifying the vectorization model.
+ *         Can be @link ParallelismTags#Vectorial @endlink or @link ParallelismTags#Serial @endlink (default).
+ *
+ * Special execution policy for computing sequence alignments with wave-front parallelization strategy.
+ * In the wave-front execution the DP matrix is partitioned into blocks which can be executed
+ * in parallel along the minor diagonal of the DP matrix.
+ * The execution policy can be further specialized if used in combination with the @link ParallelismTags#Vectorial @endlink
+ * execution mode (see @link WavefrontExecutionPolicy @endlink).
+ *
+ * @section Vectorization
+ *
+ * In the vectorization mode, the blocks are gathered into SIMD registers.
+ * The @link BlockOffsetOptimization @endlink can be used to always ensure that <tt>sizeof(SIMD) / 2</tt> many blocks
+ * can be packed into one SIMD register.
+ * This requires, that the available instruction set supports 16 bit packed SIMD operations (e.g. SSE4, AVX2)
+ * and the score value type (@link Score @endlink) is bigger then 16 bit.
+ * In the default mode, the optimization is disabled and the number of packed alignment blocks is solely determined by
+ * the score value type passed to the algorithm as a parameter (e.g. see @link globalAlignmentScore @endlink).
+ */
+ template <typename TSpec = void>
+ struct WavefrontAlignment;
+
+template <typename TSpec, typename TVectorizationSpec>
+struct ExecutionPolicy<WavefrontAlignment<TSpec>, TVectorizationSpec> :
+    public ExecutionPolicy<Parallel, TVectorizationSpec>
+{
+    /*!
+     *@var size_t WavefrontExecutionPolicy::blockSize
+     * @brief The size of the blocks to use. Defaults to 100.
+     */
+    size_t blockSize{100};
+    /*!
+     * @var size_t WavefrontExecutionPolicy::parallelAlignments
+     * @brief Number of alignments scheduled concurrently. Defaults to <tt>std::thread::hardware_concurrency()</tt>.
+     */
+    size_t parallelAlignments{std::thread::hardware_concurrency()};
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+/*!
+ * @fn WavefrontExecutionPolicy#blockSize
+ * @brief Getter for the current block size.
+ * @signature size_t blockSize(exec);
+ * @param[in] exec The wave-front execution policy to query.
+ */
+template <typename TSpec, typename TVectorizationSpec>
+inline auto
+blockSize(ExecutionPolicy<WavefrontAlignment<TSpec>, TVectorizationSpec> const & p)
+{
+    return p.blockSize;
+}
+
+/*!
+ * @fn WavefrontExecutionPolicy#setBlockSize
+ * @brief Setter for the current block size.
+ * @signature void setBlockSize(exec, bs);
+ * @param[in,out] exec The wave-front execution policy to update.
+ * @param[in] bs The new block size to set. Must be a positive integral number greater or equal than 5.
+ */
+template <typename TSpec, typename TVectorizationSpec>
+inline void
+setBlockSize(ExecutionPolicy<WavefrontAlignment<TSpec>, TVectorizationSpec> & p,
+             size_t const bs)
+{
+    SEQAN_ASSERT_GEQ(bs, static_cast<size_t>(5));
+    p.blockSize = bs;
+}
+
+/*!
+ * @fn WavefrontExecutionPolicy#parallelAlignments
+ * @brief Getter for the current number of alignments executed in parallel.
+ * @signature void parallelAlignments(exec);
+ * @param[in] exec The wave-front execution policy to update.
+ */
+template <typename TSpec, typename TVectorizationSpec>
+inline auto
+parallelAlignments(ExecutionPolicy<WavefrontAlignment<TSpec>, TVectorizationSpec> const & p)
+{
+    return p.parallelAlignments;
+}
+
+/*!
+ * @fn WavefrontExecutionPolicy#setParallelAlignments
+ * @brief Setter for the current number of alignments executed in parallel.
+ * @signature void setParallelAlignments(exec, pa);
+ * @param[in,out] exec The wave-front execution policy to update.
+ * @param[in] pa The number of alignments to execute in parallel. Must be a positive integral number greater than 0.
+ */
+template <typename TSpec, typename TVectorizationSpec>
+inline void
+setParallelAlignments(ExecutionPolicy<WavefrontAlignment<TSpec>, TVectorizationSpec> & p,
+                      size_t const pi)
+{
+    SEQAN_ASSERT_GT(pi, static_cast<size_t>(0));
+    p.parallelAlignments = pi;
+}
+
+}  // namespace seqan
+
+#endif  // INCLUDE_SEQAN_ALIGN_PARALLEL_DP_PARALLEL_EXECUTION_PLOCIES_H_
diff --git a/include/seqan/align_parallel/dp_parallel_scout.h b/include/seqan/align_parallel/dp_parallel_scout.h
new file mode 100644
index 0000000..8ee427e
--- /dev/null
+++ b/include/seqan/align_parallel/dp_parallel_scout.h
@@ -0,0 +1,263 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_H_
+#define INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Class DPTileBuffer
+// ----------------------------------------------------------------------------
+
+// The structure owning the horizontal/vertical buffer.
+template <typename TDPCellBuff, typename TBuffer = String<TDPCellBuff> >
+struct DPTileBuffer
+{
+    TBuffer horizontalBuffer;
+    TBuffer verticalBuffer;
+};
+
+// ----------------------------------------------------------------------------
+// Tag DPTiled<TBuffer>
+// ----------------------------------------------------------------------------
+
+// Tag used to subclass DPScoutState and DPScout.
+// T represents the buffer type.
+template <typename TBuffer, typename TThreadContext = Default, typename TSimdSpec = void>
+struct DPTiled;
+
+// ----------------------------------------------------------------------------
+// Class DPScoutState_; DPTiled
+// ----------------------------------------------------------------------------
+
+// The overloaded DPScoutState which simply stores the pointers to the corresponding buffer.
+template <typename TBuffer, typename TThreadContext>
+class DPScoutState_<DPTiled<TBuffer, TThreadContext, void> >
+{
+public:
+
+    using TDPCell = typename Value<typename Value<TBuffer>::Type, 1>::Type;
+
+    TBuffer* ptrHorBuffer = nullptr;
+    TBuffer* ptrVerBuffer = nullptr;
+    TThreadContext threadContext{};
+
+    DPScoutState_() = default;
+
+    DPScoutState_(TBuffer & horBuffer, TBuffer & verBuffer) :
+        ptrHorBuffer(&horBuffer),
+        ptrVerBuffer(&verBuffer)
+    {}
+
+    DPScoutState_(TBuffer & horBuffer, TBuffer & verBuffer, TThreadContext pThreadContext) :
+        ptrHorBuffer(&horBuffer),
+        ptrVerBuffer(&verBuffer),
+        threadContext(std::move(pThreadContext))
+    {}
+};
+
+// ----------------------------------------------------------------------------
+// Class DPScout_; DPTiled
+// ----------------------------------------------------------------------------
+
+// Overloaded DPScout to store the corresponding buffer for the current dp tile.
+template <typename TDPCell, typename TBuffer, typename TThreadContext>
+class DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, void> > :
+    public DPScout_<TDPCell, Default>
+{
+public:
+    using TBase = DPScout_<TDPCell, Default>;
+
+    DPScoutState_<DPTiled<TBuffer, TThreadContext, void> > state;
+
+    size_t   horizontalPos;
+    size_t   verticalPos;
+    bool     forceTracking;
+
+    DPScout_(DPScoutState_<DPTiled<TBuffer, TThreadContext, void> > state,
+             bool pForceTracking = false) :
+        TBase(),
+        state(state),
+        forceTracking(pForceTracking)
+    {}
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Metafunction ScoutSpecForSimdAlignment_
+// ----------------------------------------------------------------------------
+
+template<typename TAlignmentAlgorithm, typename TThreadContext, typename TBuffer>
+struct ScoutSpecForAlignmentAlgorithm_<TAlignmentAlgorithm, DPScoutState_<DPTiled<TBuffer, TThreadContext, void> > >
+{
+    using Type = DPTiled<TBuffer, TThreadContext, void>;
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSpec,
+          typename TIsLastColumn,
+          typename TIsLastRow>
+inline bool
+isTrackingEnabled(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, TSpec> > const & /*dpScout*/,
+                  TIsLastColumn const & /*unused*/,
+                  TIsLastRow const & /*unused*/)
+{
+    return false;
+}
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext>
+inline bool
+isTrackingEnabled(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, void> > const & dpScout,
+                  True const & /*unused*/,
+                  True const & /*unused*/)
+{
+    return (dpScout.forceTracking || (dpScout.state.threadContext.task._lastHBlock &&
+                                       dpScout.state.threadContext.task._lastVBlock));
+}
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext>
+inline bool
+isTrackingEnabled(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, void> > const & dpScout,
+                  True const & /*unused*/,
+                  False const & /*unused*/)
+{
+    return (dpScout.forceTracking || dpScout.state.threadContext.task._lastHBlock);
+}
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext>
+inline bool
+isTrackingEnabled(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, void> > const & dpScout,
+                  False const & /*unused*/,
+                  True const & /*unused*/)
+{
+    return (dpScout.forceTracking || dpScout.state.threadContext.task._lastVBlock);
+}
+
+// ----------------------------------------------------------------------------
+// Function _scoutBestScore()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer,
+          typename TTraceMatrixNavigator,
+          typename TIsLastColumn,
+          typename TIsLastRow>
+inline void
+_scoutBestScore(DPScout_<TDPCell, DPTiled<TBuffer, Default, void> > & dpScout,
+                TDPCell const & activeCell,
+                TTraceMatrixNavigator const & navigator,
+                TIsLastColumn const & isLastColumn,
+                TIsLastRow const & isLastRow)
+{
+    using TBaseScout = typename DPScout_<TDPCell, DPTiled<TBuffer, Default, void> >::TBase;
+    _scoutBestScore(static_cast<TBaseScout&>(dpScout), activeCell, navigator, isLastColumn, isLastRow);
+}
+
+// Tracks the new score, if it is the new maximum.
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraceMatrixNavigator,
+          typename TIsLastColumn, typename TIsLastRow>
+inline void
+_scoutBestScore(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, void> > & dpScout,
+                TDPCell const & activeCell,
+                TTraceMatrixNavigator const & navigator,
+                TIsLastColumn const & isLastColumn,
+                TIsLastRow const & isLastRow)
+{
+    using TBaseScout = typename DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, void> >::TBase;
+    if (isTrackingEnabled(dpScout, isLastColumn, isLastRow))
+        _scoutBestScore(static_cast<TBaseScout&>(dpScout), activeCell, navigator, isLastColumn, isLastRow);
+}
+
+// ----------------------------------------------------------------------------
+// Function _preInitScoutHorizontal()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSpec>
+inline void
+_preInitScoutHorizontal(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, TSpec> > & scout)
+{
+    scout.horizontalPos = 0;
+}
+
+// ----------------------------------------------------------------------------
+// Function _preInitScoutVertical()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSpec>
+inline void
+_preInitScoutVertical(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, TSpec> > & scout)
+{
+    scout.verticalPos = 0;
+}
+
+// ----------------------------------------------------------------------------
+// Function _incHorizontalPos()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSpec>
+inline void
+_incHorizontalPos(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, TSpec> > & scout)
+{
+    ++scout.horizontalPos;
+}
+
+// ----------------------------------------------------------------------------
+// Function _incVerticalPos()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSpec>
+inline void
+_incVerticalPos(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, TSpec> > & scout)
+{
+    ++scout.verticalPos;
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_H_
diff --git a/include/seqan/align_parallel/dp_parallel_scout_simd.h b/include/seqan/align_parallel/dp_parallel_scout_simd.h
new file mode 100644
index 0000000..db1dfc3
--- /dev/null
+++ b/include/seqan/align_parallel/dp_parallel_scout_simd.h
@@ -0,0 +1,362 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_SIMD_H_
+#define INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_SIMD_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Class DPScoutState_; DPTiled
+// ----------------------------------------------------------------------------
+
+// The overloaded DPScoutState which simply stores the pointers to the corresponding buffer.
+template <typename TBuffer, typename TThreadContext, typename TSimdSpec>
+class DPScoutState_<DPTiled<TBuffer, TThreadContext, TSimdSpec> > :
+    public DPScoutState_<DPTiled<TBuffer, TThreadContext, void> >,
+    public DPScoutState_<TSimdSpec>
+{
+public:
+
+    DPScoutState_() = default;
+
+    DPScoutState_(TBuffer & horBuffer, TBuffer & verBuffer) :
+        DPScoutState_<DPTiled<TBuffer, TThreadContext, void> >(horBuffer, verBuffer),
+        DPScoutState_<TSimdSpec>()
+    {}
+
+    DPScoutState_(TBuffer & horBuffer, TBuffer & verBuffer, TThreadContext && pThreadContext) :
+        DPScoutState_<DPTiled<TBuffer, TThreadContext, void> >(horBuffer, verBuffer, std::move(pThreadContext)),
+        DPScoutState_<TSimdSpec>()
+    {}
+};
+
+// ----------------------------------------------------------------------------
+// Class DPScout_; DPTiled
+// ----------------------------------------------------------------------------
+
+// Overloaded DPScout to store the corresponding buffer for the current dp tile.
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSimdSpec>
+class DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > > :
+    public DPScout_<TDPCell, SimdAlignmentScout<TSimdSpec>>
+{
+public:
+    using TBase = DPScout_<TDPCell, SimdAlignmentScout<TSimdSpec> >;
+
+    DPScoutState_<DPTiled<TBuffer, TThreadContext, TSimdSpec> > state;
+    size_t   horizontalPos;
+    size_t   verticalPos;
+    bool  forceTracking;
+
+    DPScout_(DPScoutState_<DPTiled<TBuffer, TThreadContext, TSimdSpec> > & state,
+             bool const pForceTracking) :
+        TBase(static_cast<DPScoutState_<TSimdSpec>&>(state)),
+        state(state),
+        forceTracking(pForceTracking)
+    {}
+
+    DPScout_(DPScoutState_<DPTiled<TBuffer, TThreadContext, TSimdSpec> > & state) : DPScout_(state, false)
+    {}
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Metafunction ScoutSpecForSimdAlignment_
+// ----------------------------------------------------------------------------
+
+template<typename TAlignmentAlgorithm, typename TBuffer, typename TThreadContext>
+struct ScoutSpecForAlignmentAlgorithm_<TAlignmentAlgorithm,
+                                       DPScoutState_<DPTiled<TBuffer, TThreadContext, SimdAlignEqualLength> > >
+{
+    using Type = DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<SimdAlignEqualLength> >;
+};
+
+template<typename TAlignmentAlgorithm, typename TBuffer, typename TThreadContext, typename TTraits>
+struct ScoutSpecForAlignmentAlgorithm_<TAlignmentAlgorithm,
+                                       DPScoutState_<DPTiled<TBuffer,
+                                                             TThreadContext,
+                                                             SimdAlignVariableLength<TTraits> > > >
+{
+    using Type = DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > >;
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Function isTrackingEnabled()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSimdSpec>
+inline bool
+isTrackingEnabled(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > > const & dpScout,
+                  True const & /*unused*/,
+                  True const & /*unused*/)
+{
+    // TODO(rrahn): Implement me!
+    return (dpScout.forceTracking);
+}
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSimdSpec>
+inline bool
+isTrackingEnabled(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > > const & dpScout,
+                  True const & /*unused*/,
+                  False const & /*unused*/)
+{
+    // TODO(rrahn): Implement me!
+    return (dpScout.forceTracking);
+}
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSimdSpec>
+inline bool
+isTrackingEnabled(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > > const & dpScout,
+                  False const & /*unused*/,
+                  True const & /*unused*/)
+{
+    // TODO(rrahn): Implement me!
+    return (dpScout.forceTracking);
+}
+
+// ----------------------------------------------------------------------------
+// Function _scoutBestScore()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSimdSpec,
+          typename TTraceMatrixNavigator,
+          typename TIsLastColumn,
+          typename TIsLastRow>
+inline void
+_scoutBestScore(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > > & dpScout,
+                TDPCell const & activeCell,
+                TTraceMatrixNavigator const & navigator,
+                TIsLastColumn const & isLastColumn,
+                TIsLastRow const & isLastRow)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec>>>::TBase;
+    _scoutBestScore(static_cast<TScoutBase&>(dpScout), activeCell, navigator, isLastColumn, isLastRow);
+}
+
+// ----------------------------------------------------------------------------
+// Function maxHostCoordinate()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSimdSpec,
+typename TDimension>
+inline auto
+maxHostCoordinate(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > > const & dpScout,
+                  TDimension const dimension)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > >::TBase;
+    return maxHostCoordinate(static_cast<TScoutBase const &>(dpScout), dimension);
+}
+
+// ----------------------------------------------------------------------------
+// Function _setSimdLane()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TSimdSpec,
+typename TPosition>
+inline void
+_setSimdLane(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > > & dpScout,
+             TPosition const pos)
+{
+    using TScoutBase = typename DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<TSimdSpec> > >::TBase;
+    _setSimdLane(static_cast<TScoutBase&>(dpScout), pos);
+}
+
+// ----------------------------------------------------------------------------
+// Function _preInitScoutHorizontal()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraits>
+inline void
+_preInitScoutHorizontal(DPScout_<TDPCell, DPTiled<TBuffer, TThreadContext, SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > > & scout)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer,
+                                                 TThreadContext,
+                                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits>>>>::TBase;
+    _preInitScoutHorizontal(static_cast<TScoutBase&>(scout));
+    scout.horizontalPos = 0;
+}
+
+// ----------------------------------------------------------------------------
+// Function _preInitScoutVertical()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraits>
+inline void
+_preInitScoutVertical(DPScout_<TDPCell,
+                               DPTiled<TBuffer,
+                                       TThreadContext,
+                                       SimdAlignmentScout<SimdAlignVariableLength<TTraits>>>> & scout)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer,
+                                                 TThreadContext,
+                                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits>>>>::TBase;
+    _preInitScoutVertical(static_cast<TScoutBase&>(scout));
+    scout.verticalPos = 0;
+}
+
+// ----------------------------------------------------------------------------
+// Function _reachedHorizontalEndPoint()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraits, typename TIter>
+inline bool
+_reachedHorizontalEndPoint(DPScout_<TDPCell,
+                                    DPTiled<TBuffer,
+                                            TThreadContext,
+                                            SimdAlignmentScout<SimdAlignVariableLength<TTraits>>>> & scout,
+                           TIter const & hIt)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer,
+                                                 TThreadContext,
+                                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits>>>>::TBase;
+    return _reachedHorizontalEndPoint(static_cast<TScoutBase&>(scout), hIt);
+}
+
+// ----------------------------------------------------------------------------
+// Function _reachedVerticalEndPoint()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraits, typename TIter>
+inline bool
+_reachedVerticalEndPoint(DPScout_<TDPCell,
+                                  DPTiled<TBuffer,
+                                          TThreadContext,
+                                          SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > > & scout,
+                         TIter const & vIt)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer,
+                                                 TThreadContext,
+                                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > >::TBase;
+    return _reachedVerticalEndPoint(static_cast<TScoutBase&>(scout), vIt);
+}
+
+// ----------------------------------------------------------------------------
+// Function _nextHorizontalEndPos()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraits>
+inline void
+_nextHorizontalEndPos(DPScout_<TDPCell,
+                               DPTiled<TBuffer,
+                                       TThreadContext,
+                                       SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > > & scout)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer,
+                                                 TThreadContext,
+                                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > >::TBase;
+    _nextHorizontalEndPos(static_cast<TScoutBase&>(scout));
+}
+
+// ----------------------------------------------------------------------------
+// Function _nextVerticalEndPos()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraits>
+inline void
+_nextVerticalEndPos(DPScout_<TDPCell,
+                             DPTiled<TBuffer,
+                                     TThreadContext,
+                                     SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > > & scout)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer,
+                                                 TThreadContext,
+                                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > >::TBase;
+    _nextVerticalEndPos(static_cast<TScoutBase&>(scout));
+}
+
+// ----------------------------------------------------------------------------
+// Function _incHorizontalPos()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraits>
+inline void
+_incHorizontalPos(DPScout_<TDPCell,
+                           DPTiled<TBuffer,
+                                   TThreadContext,
+                                   SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > > & scout)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer,
+                                                 TThreadContext,
+                                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > >::TBase;
+    _incHorizontalPos(static_cast<TScoutBase&>(scout));
+    ++scout.horizontalPos;
+}
+
+// ----------------------------------------------------------------------------
+// Function _incVerticalPos()
+// ----------------------------------------------------------------------------
+
+template <typename TDPCell, typename TBuffer, typename TThreadContext, typename TTraits>
+inline void
+_incVerticalPos(DPScout_<TDPCell,
+                         DPTiled<TBuffer,
+                                 TThreadContext,
+                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > > & scout)
+{
+    using TScoutBase = typename DPScout_<TDPCell,
+                                         DPTiled<TBuffer,
+                                                 TThreadContext,
+                                                 SimdAlignmentScout<SimdAlignVariableLength<TTraits> > > >::TBase;
+    _incVerticalPos(static_cast<TScoutBase&>(scout));
+    ++scout.verticalPos;
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_DP_PARALLEL_DP_PARALLEL_SCOUT_SIMD_H_
diff --git a/include/seqan/parallel/parallel_tags.h b/include/seqan/align_parallel/dp_settings.h
similarity index 55%
copy from include/seqan/parallel/parallel_tags.h
copy to include/seqan/align_parallel/dp_settings.h
index 20d395c..26ee76d 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/include/seqan/align_parallel/dp_settings.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
@@ -29,15 +29,14 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tags to select serial/parallel algorithms.
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
-#define SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_SETTINGS_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_SETTINGS_H_
 
-namespace seqan {
+namespace seqan
+{
 
 // ============================================================================
 // Forwards
@@ -47,40 +46,64 @@ namespace seqan {
 // Tags, Classes, Enums
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Tag Parallel
-// ----------------------------------------------------------------------------
-
-/*!
- * @defgroup ParallelismTags Parallelism Tags
- * @brief Tags for enabling/disabling parallelism.
- *
- * @tag ParallelismTags#Parallel
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the parallel implementation of an algorithm.
- *
- * @tag ParallelismTags#Serial
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the serial implementation of an algorithm.
- */
-
-struct Parallel_;
-typedef Tag<Parallel_> Parallel;
+// Translates global function interface into setting struct.
+template <typename TScoringScheme_, typename TDPTraits = DPTraits::GlobalLinear>
+struct DPSettings
+{
+    using TTraits        = TDPTraits;
+    using TScoringScheme = TScoringScheme_;
+    using TBandConfig    = DPBandConfig<typename TDPTraits::TBandType>;
 
-// ============================================================================
-// Metafunctions
-// ============================================================================
+    TScoringScheme  scoringScheme;
+    TBandConfig     bandScheme;
+
+    DPSettings() = default;
 
-// ----------------------------------------------------------------------------
-// Metafunction DefaultParallelSpec
-// ----------------------------------------------------------------------------
+    explicit DPSettings(TScoringScheme score) : scoringScheme(std::move(score))
+    {}
+};
 
-template <typename TObject>
-struct DefaultParallelSpec
+#ifdef SEQAN_SIMD_ENABLED
+// Simd version of DP settings.
+template <typename TDPSettings, typename TOffsetSpec = False>
+struct SimdDPSettings : public TDPSettings
 {
-    typedef Parallel Type;
+    //-------------------------------------------------------------------------
+    // Member Types.
+
+    using TTraits = typename TDPSettings::TTraits;
+    using TScoringScheme = typename TDPSettings::TScoringScheme;
+    using TScoreValue = typename Value<TScoringScheme>::Type;
+    using TScoreValueSimd = typename SimdVector<
+                                        std::conditional_t<std::is_same<TOffsetSpec, BlockOffsetOptimization>::value,
+                                                           int16_t,
+                                                           TScoreValue>>::Type;
+    using TSimdScoringScheme = Score<TScoreValueSimd, ScoreSimdWrapper<TScoringScheme>>;
+
+    //-------------------------------------------------------------------------
+    // Members.
+
+    TSimdScoringScheme  simdScoringScheme;
+
+    //-------------------------------------------------------------------------
+    // Constructor.
+
+    SimdDPSettings() = default;
+
+    explicit SimdDPSettings(TScoringScheme score) :
+        TDPSettings(std::move(score)),
+        simdScoringScheme(score)
+    {}
 };
+#endif  // SEQAN_SIMD_ENABLED
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
 
 }  // namespace seqan
 
-#endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#endif  // INCLUDE_SEQAN_ALIGN_PARALLEL_DP_SETTINGS_H_
diff --git a/include/seqan/parallel/parallel_tags.h b/include/seqan/align_parallel/dp_traits.h
similarity index 54%
copy from include/seqan/parallel/parallel_tags.h
copy to include/seqan/align_parallel/dp_traits.h
index 20d395c..f3a5c6d 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/include/seqan/align_parallel/dp_traits.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
@@ -29,15 +29,14 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tags to select serial/parallel algorithms.
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
-#define SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_TRAITS_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_TRAITS_H_
 
-namespace seqan {
+namespace seqan
+{
 
 // ============================================================================
 // Forwards
@@ -47,40 +46,75 @@ namespace seqan {
 // Tags, Classes, Enums
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Tag Parallel
-// ----------------------------------------------------------------------------
-
-/*!
- * @defgroup ParallelismTags Parallelism Tags
- * @brief Tags for enabling/disabling parallelism.
- *
- * @tag ParallelismTags#Parallel
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the parallel implementation of an algorithm.
- *
- * @tag ParallelismTags#Serial
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the serial implementation of an algorithm.
- */
-
-struct Parallel_;
-typedef Tag<Parallel_> Parallel;
+// Traits for DP configuration. Currently used only internally.
+struct DPTraits
+{
+    // Gocal alignment with linear gap costs.
+    struct GlobalLinear
+    {
+        // The algorithm to choose.
+        using TAlgorithmType    = GlobalAlignment_<>;
+        // The Gaps to choos
+        using TGapType          = LinearGaps;
+        // The Band to choose.
+        using TBandType         = BandOff;
+        // The traceback.
+        using TTracebackType    = TracebackOn<TracebackConfig_<SingleTrace, GapsLeft>>;
+        // The output to choose.
+        using TFormat           = ArrayGaps;
+    };
+
+    // Global alignment with affine gap costs.
+    struct GlobalAffine : public GlobalLinear
+    {
+        using TGapType          = AffineGaps;
+    };
+
+    // Global alignment with affine gap costs.
+    struct SemiGlobalLinear : public GlobalLinear
+    {
+        using TAlgorithmType = GlobalAlignment_<FreeEndGaps_<True, False, True, False>>;
+    };
+
+    // Global alignment with affine gap costs.
+    struct SemiGlobalAffine : public GlobalAffine
+    {
+        using TAlgorithmType = GlobalAlignment_<FreeEndGaps_<True, False, True, False>>;
+    };
+
+    // Banded global alignment with linear gap costs.
+    struct BandedGlobalLinear : public GlobalLinear
+    {
+        using TBandType         = BandOn;
+    };
+
+    // Banded global alignment with affine gap costs.
+    struct BandedGlobalAffine : public BandedGlobalLinear
+    {
+        using TGapType          = AffineGaps;
+    };
+
+    // Local alignment with linear gap costs.
+    struct LocalLinear : public GlobalLinear
+    {
+        using TAlgorithmType    = LocalAlignment_<>;
+    };
+
+    // Local alignment with affine gap costs.
+    struct LocalAffine : public LocalLinear
+    {
+        using TGapType          = AffineGaps;
+    };
+};
 
 // ============================================================================
 // Metafunctions
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Metafunction DefaultParallelSpec
-// ----------------------------------------------------------------------------
-
-template <typename TObject>
-struct DefaultParallelSpec
-{
-    typedef Parallel Type;
-};
+// ============================================================================
+// Functions
+// ============================================================================
 
 }  // namespace seqan
 
-#endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#endif  // INCLUDE_SEQAN_ALIGN_PARALLEL_DP_TRAITS_H_
diff --git a/include/seqan/align_parallel/parallel_align_interface.h b/include/seqan/align_parallel/parallel_align_interface.h
new file mode 100644
index 0000000..db7ee0c
--- /dev/null
+++ b/include/seqan/align_parallel/parallel_align_interface.h
@@ -0,0 +1,366 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_ALIGN_INTERFACE_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_ALIGN_INTERFACE_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+namespace impl
+{
+
+/*
+ * Executor class that implements the correct execution mode.
+ */
+struct ParallelAlignmentExecutor
+{
+    template <typename TKernel,
+              typename TSetH,
+              typename TSetV,
+              typename ...TArgs>
+    auto operator()(Sequential const & /*execPolicy*/,
+                    TKernel && kernel,
+                    TSetH const & setH,
+                    TSetV const & setV,
+                    TArgs && ...args)
+    {
+        SEQAN_ASSERT_EQ(length(setH), length(setV));
+
+        using TResult = decltype(kernel(setH, setV, std::forward<TArgs>(args)...));
+
+        TResult superSet;
+        resize(superSet, length(setH));
+
+        auto zipCont = makeZipView(setH, setV, superSet);
+#ifdef DP_PARALLEL_SHOW_PROGRESS
+        ::impl::dp_parallel_progress::show_progress(length(setH));
+#endif  // DP_PARALLEL_SHOW_PROGRESS
+        for (auto && pwInst : zipCont)
+        {
+            std::get<2>(pwInst) = kernel(std::get<0>(pwInst), std::get<1>(pwInst), std::forward<TArgs>(args)...);
+        }
+        return superSet;
+    }
+
+    template <typename TKernel,
+              typename TSetH,
+              typename ...TArgs>
+    auto operator()(ExecutionPolicy<Serial, Vectorial> const & /*execPolicy*/,
+                    TKernel && kernel,
+                    TSetH const & setH,
+                    TArgs && ...args)
+    {
+#ifdef DP_PARALLEL_SHOW_PROGRESS
+        ::impl::dp_parallel_progress::show_progress(length(setH));
+#endif  // DP_PARALLEL_SHOW_PROGRESS
+        // Automaically chooses vectorized code, or falls back to sequential code.
+        return kernel(setH, std::forward<TArgs>(args)...);
+    }
+
+    template <typename TKernel,
+              typename TSetH,
+              typename TSetV,
+              typename ...TArgs>
+    auto operator()(SEQAN_UNUSED ExecutionPolicy<Parallel, Vectorial> const & execPolicy,  // maybe unused due to missing OMP support in clang.
+                    TKernel && kernel,
+                    TSetH const & setH,
+                    TSetV const & setV,
+                    TArgs && ...args)
+
+    {
+        SEQAN_ASSERT_EQ(length(setH), length(setV));
+
+        using TPos = std::make_signed_t<decltype(length(setH))>;
+        using TResult = decltype(kernel(setH, setV, std::forward<TArgs>(args)...));
+
+        TPos chunkSize = _min(static_cast<TPos>(length(setH)), static_cast<TPos>(256));
+        String<TPos> splitter;
+        computeSplitters(splitter, length(setH), static_cast<TPos>(length(setH)/chunkSize));
+
+        std::vector<TResult> superSet;
+        superSet.resize(length(splitter));
+
+#ifdef DP_PARALLEL_SHOW_PROGRESS
+        ::impl::dp_parallel_progress::show_progress(length(setH));
+#endif  // DP_PARALLEL_SHOW_PROGRESS
+
+        SEQAN_OMP_PRAGMA(parallel for num_threads(numThreads(execPolicy)) schedule(guided))
+        for (TPos job = 0; job < static_cast<TPos>(length(splitter)) - 1; ++job)  // TODO(rrahn): Why -1; Is there a bug in computeSplitters?
+        {
+            auto infSetH = infix(setH, splitter[job], splitter[job + 1]);
+            auto infSetV = infix(setV, splitter[job], splitter[job + 1]);
+
+            superSet[job] = kernel(infSetH, infSetV, std::forward<TArgs>(args)...);
+        }
+        // Reduce the result.
+        TResult res;
+        resize(res, length(setH));
+        auto it = begin(res, Standard());
+        for (auto && set : superSet)
+        {
+            arrayMoveForward(begin(set, Standard()), end(set, Standard()), it);
+            it += length(set);
+        }
+        return res;
+    }
+
+    template <typename TKernel,
+              typename TSetH,
+              typename TSetV,
+              typename ...TArgs>
+    auto operator()(ExecutionPolicy<Parallel, Serial> const & execPolicy,
+                    TKernel && kernel,
+                    TSetH const & setH,
+                    TSetV const & setV,
+                    TArgs && ...args)
+
+    {
+        SEQAN_ASSERT_EQ(length(setH), length(setV));
+
+        using TPos = std::make_signed_t<decltype(length(setH))>;
+        using TResult = decltype(kernel(setH, setV, std::forward<TArgs>(args)...));
+
+        Splitter<TPos> splitter(0, length(setH), numThreads(execPolicy));
+
+        TResult superSet;
+        resize(superSet, length(setH));
+
+        auto zipCont = makeZipView(setH, setV, superSet);
+
+#ifdef DP_PARALLEL_SHOW_PROGRESS
+        ::impl::dp_parallel_progress::show_progress(length(setH));
+#endif  // DP_PARALLEL_SHOW_PROGRESS
+
+        SEQAN_OMP_PRAGMA(parallel for num_threads(length(splitter)))
+        for (TPos job = 0; job < static_cast<TPos>(length(splitter)); ++job)
+        {
+            auto it = begin(zipCont, Standard()) + splitter[job];
+            auto itEnd = begin(zipCont, Standard()) + splitter[job + 1];
+
+            // NOTE(marehr): auto && seqPair does not work, thus declaring the
+            // type explicitly, s.t. <=icpc 18.0.1 can compile the code (ticket
+            // #03204483)
+            using TSeqPair = decltype(*it);
+            std::for_each(it, itEnd, [&](TSeqPair && seqPair)
+            {
+                std::get<2>(seqPair) = kernel(std::get<0>(seqPair), std::get<1>(seqPair), std::forward<TArgs>(args)...);
+            });
+        }
+        return superSet;
+    }
+};
+
+template <typename TWaveSpec, typename TVectorizationPolicy,
+          typename TAlgorithmSpec,
+          typename TSetH,
+          typename TSetV,
+          typename TScore,
+          typename ...TArgs,
+          std::enable_if_t<!std::is_same<WavefrontAlignment<TWaveSpec>, Serial>::value &&
+                           !std::is_same<WavefrontAlignment<TWaveSpec>, Parallel>::value,
+                           int> = 0>
+inline auto
+doWaveAlignment(ExecutionPolicy<WavefrontAlignment<TWaveSpec>, TVectorizationPolicy> const & execPolicy,
+                TAlgorithmSpec const & /*tag*/,
+                TSetH const & setH,
+                TSetV const & setV,
+                TScore const & scoringScheme,
+                TArgs && .../*args*/)
+{
+    using TScoreValue = typename Value<TScore>::Type;
+
+    // The vector containing the scores.
+    std::vector<TScoreValue> res;
+    res.resize(length(setH));
+
+    auto dispatcher = [&res](auto && ...args)
+    {
+        alignExecBatch(std::forward<decltype(args)>(args)...,
+                             [&res](auto const id, auto const score)
+                             {
+                                 res[id] = score;
+                             });
+    };
+
+    // Differentiate between affine and linear gap costs.
+    // TODO(rrahn): Setup configuration cascade.
+    if (scoreGapOpen(scoringScheme) == scoreGapExtend(scoringScheme))
+    {
+        struct DPConfigTraits
+        {
+            using TAlgorithmType SEQAN_UNUSED = TAlgorithmSpec;
+            using TGapType       SEQAN_UNUSED = LinearGaps;
+            using TBandType      SEQAN_UNUSED = BandOff;
+            using TTracebackType SEQAN_UNUSED = TracebackOff;
+            using TFormat        SEQAN_UNUSED = ArrayGaps;
+        };
+
+        using TDPSettings = seqan::DPSettings<TScore, DPConfigTraits>;
+
+        TDPSettings settings;
+        settings.scoringScheme = scoringScheme;
+        dispatcher(execPolicy, setH, setV, settings);
+    }
+    else
+    {
+        struct DPConfigTraits
+        {
+            using TAlgorithmType SEQAN_UNUSED = TAlgorithmSpec;
+            using TGapType       SEQAN_UNUSED = AffineGaps;
+            using TBandType      SEQAN_UNUSED = BandOff;
+            using TTracebackType SEQAN_UNUSED = TracebackOff;
+            using TFormat        SEQAN_UNUSED = ArrayGaps;
+        };
+
+        using TDPSettings = seqan::DPSettings<TScore, DPConfigTraits>;
+
+        TDPSettings settings;
+        settings.scoringScheme = scoringScheme;
+        dispatcher(execPolicy, setH, setV, settings);
+    }
+    return res;
+}
+
+} // namespace impl
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+/*
+ * Wrapper functions for calling globalAlignmentScore and localAlignmentScore with an ExecutionPolicy.
+ * Note the parallel interfaces are documented as part of the standard documentation in seqan/align module.
+ */
+template <typename TParallelPolicy, typename TVectorizationPolicy,
+          typename ...TArgs,
+          std::enable_if_t<std::is_same<TParallelPolicy, Serial>::value ||
+                           std::is_same<TParallelPolicy, Parallel>::value,
+                           int> = 0>
+inline auto
+globalAlignmentScore(ExecutionPolicy<TParallelPolicy, TVectorizationPolicy> const & execPolicy,
+                     TArgs && ...args)
+{
+    auto kernel = [](auto && ...args)
+    {
+        return globalAlignmentScore(std::forward<decltype(args)>(args)...);
+    };
+    return impl::ParallelAlignmentExecutor{}(execPolicy, kernel, std::forward<TArgs>(args)...);
+}
+
+template <typename TParallelPolicy, typename TVectorizationPolicy,
+          typename ...TArgs,
+          std::enable_if_t<std::is_same<TParallelPolicy, Serial>::value ||
+                           std::is_same<TParallelPolicy, Parallel>::value,
+                           int> = 0>
+inline auto
+localAlignmentScore(ExecutionPolicy<TParallelPolicy, TVectorizationPolicy> const & execPolicy,
+                    TArgs && ...args)
+{
+    auto kernel = [](auto && ...args)
+    {
+        return localAlignmentScore(std::forward<decltype(args)>(args)...);
+    };
+    return impl::ParallelAlignmentExecutor{}(execPolicy, kernel, std::forward<TArgs>(args)...);
+}
+
+// Wavefront execution of globalAlignmentScore w/ config.
+template <typename TWaveSpec, typename TVectorizationPolicy,
+          typename TSetH,
+          typename TSetV,
+          typename TScore,
+          typename TConfig,
+          std::enable_if_t<!std::is_same<WavefrontAlignment<TWaveSpec>, Serial>::value &&
+                           !std::is_same<WavefrontAlignment<TWaveSpec>, Parallel>::value,
+                           int> = 0>
+
+inline auto
+globalAlignmentScore(ExecutionPolicy<WavefrontAlignment<TWaveSpec>, TVectorizationPolicy> const & execPolicy,
+                     TSetH const & setH,
+                     TSetV const & setV,
+                     TScore const & scoringScheme,
+                     TConfig const & /*config*/)
+{
+    return impl::doWaveAlignment(execPolicy,
+                                 GlobalAlignment_<typename SubstituteAlignConfig_<TConfig>::Type>{},
+                                 setH,
+                                 setV,
+                                 scoringScheme);
+}
+
+// Wavefront execution of globalAlignmentScore w/o config.
+template <typename TWaveSpec, typename TVectorizationPolicy,
+          typename TSetH,
+          typename TSetV,
+          typename TScore,
+          std::enable_if_t<!std::is_same<WavefrontAlignment<TWaveSpec>, Serial>::value &&
+                           !std::is_same<WavefrontAlignment<TWaveSpec>, Parallel>::value,
+                           int> = 0>
+
+inline auto
+globalAlignmentScore(ExecutionPolicy<WavefrontAlignment<TWaveSpec>, TVectorizationPolicy> const & execPolicy,
+                     TSetH const & setH,
+                     TSetV const & setV,
+                     TScore const & scoringScheme)
+{
+    return globalAlignmentScore(execPolicy, setH, setV, scoringScheme, AlignConfig<>{});
+}
+
+template <typename TWaveSpec, typename TVectorizationPolicy,
+          typename ...TArgs,
+          std::enable_if_t<!std::is_same<WavefrontAlignment<TWaveSpec>, Serial>::value &&
+                           !std::is_same<WavefrontAlignment<TWaveSpec>, Parallel>::value,
+                           int> = 0>
+inline auto
+localAlignmentScore(ExecutionPolicy<WavefrontAlignment<TWaveSpec>, TVectorizationPolicy> const & execPolicy,
+                    TArgs && ...args)
+{
+    return impl::doWaveAlignment(execPolicy, LocalAlignment_<>{}, std::forward<TArgs>(args)...);
+}
+
+}  // namespace seqan
+
+#endif  // INCLUDE_SEQAN_ALIGN_PARALLEL_ALIGN_INTERFACE_H_
diff --git a/include/seqan/parallel/parallel_tags.h b/include/seqan/align_parallel/wavefront_alignment_executor.h
similarity index 59%
copy from include/seqan/parallel/parallel_tags.h
copy to include/seqan/align_parallel/wavefront_alignment_executor.h
index 20d395c..47cde43 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/include/seqan/align_parallel/wavefront_alignment_executor.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
@@ -29,15 +29,14 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tags to select serial/parallel algorithms.
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
-#define SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_EXECUTOR_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_EXECUTOR_H_
 
-namespace seqan {
+namespace seqan
+{
 
 // ============================================================================
 // Forwards
@@ -47,40 +46,53 @@ namespace seqan {
 // Tags, Classes, Enums
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Tag Parallel
-// ----------------------------------------------------------------------------
+// Executor class for an alignment task in the wave-front model.
+// Stores the scheduler and the thread local storage.
+template <typename TScheduler, typename TThreadLocalStore>
+struct WavefrontAlignmentExecutor
+{
+    // Shared data in parallel context.
+    TScheduler *                  ptrTaskScheduler{nullptr};
+    TThreadLocalStore *           ptrThreadLocal{nullptr};
 
-/*!
- * @defgroup ParallelismTags Parallelism Tags
- * @brief Tags for enabling/disabling parallelism.
- *
- * @tag ParallelismTags#Parallel
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the parallel implementation of an algorithm.
- *
- * @tag ParallelismTags#Serial
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the serial implementation of an algorithm.
- */
+    //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type.
+    WavefrontAlignmentExecutor() = default;
 
-struct Parallel_;
-typedef Tag<Parallel_> Parallel;
+    WavefrontAlignmentExecutor(TScheduler * _ptrScheduler,
+                               TThreadLocalStore * _ptrTls) :
+            ptrTaskScheduler{_ptrScheduler},
+            ptrThreadLocal(_ptrTls)
+    {}
+};
 
 // ============================================================================
 // Metafunctions
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Metafunction DefaultParallelSpec
-// ----------------------------------------------------------------------------
+// ============================================================================
+// Functions
+// ============================================================================
 
-template <typename TObject>
-struct DefaultParallelSpec
+// Asynchronosly schedule a new alignment job.
+template <typename ...TArgs,
+          typename TTaskExecutor>
+inline void
+spawn(WavefrontAlignmentExecutor<TArgs...> & executor,
+      TTaskExecutor && taskExec)
 {
-    typedef Parallel Type;
-};
+    SEQAN_ASSERT(executor.ptrTaskScheduler != nullptr);
+    scheduleTask(*executor.ptrTaskScheduler, std::forward<TTaskExecutor>(taskExec));
+}
+
+// Access thread local storage.
+template <typename ...TArgs>
+inline auto &
+local(WavefrontAlignmentExecutor<TArgs...> & executor)
+{
+    SEQAN_ASSERT(executor.ptrThreadLocal != nullptr);
+    return local(*executor.ptrThreadLocal);
+}
 
 }  // namespace seqan
 
-#endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_EXECUTOR_H_
diff --git a/include/seqan/align_parallel/wavefront_alignment_result.h b/include/seqan/align_parallel/wavefront_alignment_result.h
new file mode 100644
index 0000000..abcaeed
--- /dev/null
+++ b/include/seqan/align_parallel/wavefront_alignment_result.h
@@ -0,0 +1,165 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_RESULT_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_RESULT_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// The intermediate result stored by each thread independently.
+// After an alignment has been finished, the intermediate results are reduced to a global result.
+template <typename TTraits>
+struct WavefrontAlignmentResult
+{
+    // ----------------------------------------------------------------------------
+    // Member Types.
+
+    using TState = std::pair<typename TTraits::TScoreValue, typename TTraits::THostPosition>;
+
+    // ----------------------------------------------------------------------------
+    // Member Variables
+
+    TState  _maxState{std::numeric_limits<typename TTraits::TScoreValue>::min(), typename TTraits::THostPosition{}};
+    size_t  _tileCol{0};
+    size_t  _tileRow{0};
+
+    //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type.
+    // ----------------------------------------------------------------------------
+    // Constructors.
+
+    // Note: Although, this could be an aggregate type, the icpc-17 crashes,
+    // when compiling without the defaulted constructor.
+    WavefrontAlignmentResult() = default;
+
+    WavefrontAlignmentResult(TState const maxState) :
+        _maxState(std::move(maxState))
+    {}
+
+    WavefrontAlignmentResult(TState const maxState, size_t const tileCol, size_t  const tileRow) :
+        _maxState(std::move(maxState)),
+        _tileCol(tileCol),
+        _tileRow(tileRow)
+    {}
+
+    // ----------------------------------------------------------------------------
+    // Member Functions.
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+namespace impl
+{
+
+template <typename TIntermediate,
+          typename TState>
+inline void
+updateMax(TIntermediate & me,
+          TState const & state,
+          size_t const tileCol,
+          size_t const tileRow)
+{
+    if (state.first > me._maxState.first)
+    {
+        me._maxState = state;
+        me._tileCol = tileCol;
+        me._tileRow = tileRow;
+    }
+}
+}  // namespace impl
+
+// Update the intermediate result if new optimum has been found.
+template <typename ...TArgs>
+inline void
+updateMax(WavefrontAlignmentResult<TArgs...> & me,
+          typename WavefrontAlignmentResult<TArgs...>::TState const & state,
+          size_t const tileCol,
+          size_t const tileRow)
+{
+    impl::updateMax(me, state, tileCol, tileRow);
+}
+
+template <typename ...TArgs>
+inline void
+updateMax(WavefrontAlignmentResult<TArgs...> & lhs,
+          WavefrontAlignmentResult<TArgs...> const & rhs)
+{
+    impl::updateMax(lhs, rhs._maxState, rhs._tileCol, rhs._tileRow);
+}
+
+// Reset the intermediate result.
+template <typename ...TArgs>
+inline void
+clear(WavefrontAlignmentResult<TArgs...> & me)
+{
+    me = WavefrontAlignmentResult<TArgs...>{};
+}
+
+// Get the intermediate result.
+template <typename ...TArgs>
+inline typename WavefrontAlignmentResult<TArgs...>::TState const &
+value(WavefrontAlignmentResult<TArgs...> const & me)
+{
+    return me._maxState;
+}
+
+// Swap two intermediate results.
+template <typename ...TArgs>
+inline void
+swap(WavefrontAlignmentResult<TArgs...> & lhs,
+     WavefrontAlignmentResult<TArgs...> & rhs)
+{
+    // TODO (rrahn): report issue with Intel
+    WavefrontAlignmentResult<TArgs...> tmp = std::move(lhs);
+    lhs = std::move(rhs);
+    rhs = std::move(tmp);
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_RESULT_H_
diff --git a/include/seqan/align_parallel/wavefront_alignment_scheduler.h b/include/seqan/align_parallel/wavefront_alignment_scheduler.h
new file mode 100644
index 0000000..6dcd4df
--- /dev/null
+++ b/include/seqan/align_parallel/wavefront_alignment_scheduler.h
@@ -0,0 +1,347 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_PARALLEL_ALIGNMENT_SCHEDULER_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_PARALLEL_ALIGNMENT_SCHEDULER_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// Yet internal class. Might need some redesign to make it truly generic.
+/*
+ * @class WavefrontAlignmentScheduler
+ * @headerfile <align_parallel.h>
+ * @brief A generic scheduler allowing to execute callables with a ring buffer for the stored tasks.
+ *
+ * @signature class WavefrontAlignmentScheduler;
+ *
+ * This schedule is at the moment only used for the wave-front alignment execution but could be generalized later.
+ * It stores all scheduled callables in a @link ConcurrentSuspendableQueue @endlink which can hold a user defined
+ * number of callables at the same time. It then uses recycable ids to fill up the queue with waiting jobs.
+ * If the queue is full and a thread tries to add a new job, it will be suspended, until resources are freed by
+ * the scheduler.
+ */
+class WavefrontAlignmentScheduler
+{
+public:
+
+    //-------------------------------------------------------------------------
+    // Member Types.
+
+    using TCallable         = std::function<void(uint16_t)>;
+    using TAlignmentQueue   = ConcurrentQueue<TCallable, Suspendable<Limit>>;
+    using TRecycleList      = std::list<uint16_t>;
+
+    //-------------------------------------------------------------------------
+    // Private Member Variables.
+
+    WavefrontTaskScheduler  _taskScheduler;
+    ThreadPool              _pool;
+    TRecycleList            _recycableIds;
+    TAlignmentQueue         _queue;
+    bool                    _receivedEndSignal;
+
+    std::mutex              _mutexRecycleId;
+    unsigned                _numParallelAlignments;
+
+    std::mutex                       _mutexPushException;
+    std::vector<std::exception_ptr>  _exceptionPointers;
+
+    std::atomic<bool>               _isValid{true};
+
+    std::function<void()> job = [this] ()
+    {
+        while (true)
+        {
+            TCallable callable;
+            if (!popFront(callable, _queue))
+                break;  // End of thread => No writers and queue is empty.
+
+            uint16_t id = -1;
+
+            { // Receive id.
+                std::lock_guard<std::mutex> lck(_mutexRecycleId);
+                SEQAN_ASSERT_NOT(_recycableIds.empty());
+                id = _recycableIds.front();
+                _recycableIds.pop_front();
+            }
+
+            try
+            {
+                callable(id);  // invokes the alignment with assigned id.
+            }
+            catch (...)
+            {  // Catch any exception thrown by callable. Store exception, and set *this invalid.
+               // We still keep running until the queue is empty. The thread is cleaned either by,
+               // explicit wait or by destruction of *this.
+                _isValid.store(false, std::memory_order_release);
+                {
+                    std::lock_guard<std::mutex> lck(_mutexPushException);
+                    _exceptionPointers.push_back(std::current_exception());
+                }
+            }
+
+            // Check if task scheduler is still valid.
+            // If not, something went wrong, and we should not continue adding new tasks.
+            // So we propagate the invalid state to *this and break exceution chain.
+            if (!isValid(_taskScheduler))
+            {
+                _isValid.store(false, std::memory_order_release);
+            }
+
+            { // recycle id, when done.
+                std::lock_guard<std::mutex> lck(_mutexRecycleId);
+                _recycableIds.push_back(id);
+            }
+        }
+        unlockReading(_queue);  // Notify that this reader is finished.
+        unlockWriting(_taskScheduler);  // Notify that this writer is finished.
+    };
+
+    //-------------------------------------------------------------------------
+    // Constructors.
+
+    // implicitly deleted default constructor.
+
+    WavefrontAlignmentScheduler(size_t const numParallelAlignments, size_t const numParallelTasks) :
+        _taskScheduler(numParallelTasks),
+        _queue(numParallelAlignments),
+        _receivedEndSignal(false),
+        _numParallelAlignments(numParallelAlignments)
+    {
+        SEQAN_ASSERT_GT(numParallelAlignments, 0u);  // Bad if reader is 0.
+
+        // Setup recycable ids.
+        _recycableIds.resize(numParallelAlignments);
+        std::iota(std::begin(_recycableIds), std::end(_recycableIds), 0);
+
+        setReaderWriterCount(_queue, numParallelAlignments, 1);
+
+        _exceptionPointers.resize(numParallelAlignments, nullptr);
+
+        try
+        { // Create the threads here, later we can try to make lazy thread creation.
+            for (unsigned i = 0; i < numParallelAlignments; ++i)
+            {
+                spawn(_pool, job);
+            }
+        }
+        catch (...)  // Make sure all the spawned threads are safely stopped before re-throwing the exception.
+        {
+            unlockWriting(_queue);
+            waitForWriters(_taskScheduler);
+            join(_pool);
+            throw;
+        }
+
+        setWriterCount(_taskScheduler, numParallelAlignments);
+        // Notify task scheduler, that everything was setup correctly.
+        for (unsigned i = 0; i < numParallelAlignments; ++i)
+        {
+            lockWriting(_taskScheduler);
+        }
+        waitForWriters(_taskScheduler);  // Invoke task scheduler.
+    }
+
+    // Default constructor.
+    WavefrontAlignmentScheduler() : WavefrontAlignmentScheduler(16, 8)
+    {}
+
+    // Copy & Move C'tor
+    WavefrontAlignmentScheduler(WavefrontAlignmentScheduler const &) = delete;
+    WavefrontAlignmentScheduler(WavefrontAlignmentScheduler &&)      = delete;
+
+    ///-------------------------------------------------------------------------
+    // Destructor.
+
+    ~WavefrontAlignmentScheduler()
+    {
+        // Signal that no more alignments will be added.
+        if (!_receivedEndSignal)
+            unlockWriting(_queue);
+
+        SEQAN_ASSERT(_queue.writerCount == 0);
+
+        // Wait until all remaining threads are finished with their execution.
+        join(_pool);
+
+        // In destructor of thread pool we wait for the outstanding alignments to be finished
+        // and then continue destruction of the remaining members and cleaning up the stack.
+    }
+
+    // ------------------------------------------------------------------------
+    // Member Functions.
+
+    // Copy & Move assignment
+    WavefrontAlignmentScheduler& operator=(WavefrontAlignmentScheduler const &) = delete;
+    WavefrontAlignmentScheduler& operator=(WavefrontAlignmentScheduler &&)      = delete;
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template<>
+struct SchedulerTraits<WavefrontAlignmentScheduler>
+{
+    using TTask = typename WavefrontAlignmentScheduler::TCallable;
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+/*
+ * @fn WavefrontAlignmentScheduler#isValid
+ * @headerfile <align_parallel.h>
+ * @brief Checks if scheduler is in a valid state. This means that no callable has terminated with an exception.
+ */
+inline bool
+isValid(WavefrontAlignmentScheduler const & me)
+{
+    return me._isValid.load(std::memory_order_acquire);
+}
+
+/*
+ * @fn WavefrontAlignmentScheduler#scheduleTask
+ * @headerfile <align_parallel.h>
+ * @brief Adds a new task to the scheduler. Suspends until resources become available.
+ * @throws ExceptionType?
+ */
+// basic exception-safety guarantee.
+// Throws if appendValue failed.
+inline void
+scheduleTask(WavefrontAlignmentScheduler & me,
+             typename SchedulerTraits<WavefrontAlignmentScheduler>::TTask && callable)
+{
+    if (!isValid(me))
+        throw std::runtime_error("Invalid alignment scheduler!");
+
+    // Spins until there is enough space to add to the queue.
+    if (!appendValue(me._queue, std::forward<decltype(callable)>(callable)))
+        throw std::runtime_error("Invalid alignment scheduler 2!");
+}
+
+inline void
+scheduleTask(WavefrontAlignmentScheduler & me,
+             typename SchedulerTraits<WavefrontAlignmentScheduler>::TTask & callable)
+{
+    if (!isValid(me))
+        throw std::runtime_error("Invalid alignment scheduler!");
+    // Spins until there is enough space to add to the queue.
+    if(!appendValue(me._queue, callable))
+        throw std::runtime_error("Invalid alignment scheduler 2!");
+}
+
+/*
+ * @fn WavefrontAlignmentScheduler#notify
+ * @headerfile <align_parallel.h>
+ * @brief Notify the scheduler that no more jobs will follow.
+ */
+inline void
+notify(WavefrontAlignmentScheduler & me)
+{
+    unlockWriting(me._queue);
+    me._receivedEndSignal = true;
+}
+
+/*
+ * @fn WavefrontAlignmentScheduler#wait
+ * @headerfile <align_parallel.h>
+ * @brief Explicit barrier on the scheduler. Suspends until all scheduled jobs have been finsihed.
+ *
+ * Note, can dead lock if notify is never called.
+ */
+// Only possible if some other thread is signaling the end of it.
+inline void
+wait(WavefrontAlignmentScheduler & me)
+{
+    join(me._pool);
+    wait(me._taskScheduler);
+}
+
+/*
+ * @fn WavefrontAlignmentScheduler#wait2
+ * @headerfile <align_parallel.h>
+ * @brief Explicit barrier on the scheduler. Suspends until all scheduled jobs have been finsihed.
+ *
+ * Note, can dead lock if notify is never called.
+ */
+template <typename TNotifiable>
+inline void
+wait2(WavefrontAlignmentScheduler & me, TNotifiable & notifiable)
+{
+    join(me._pool);
+    notify(notifiable);
+    wait(me._taskScheduler);
+}
+
+/*
+ * @fn WavefrontAlignmentScheduler#getExceptions
+ * @headerfile <align_parallel.h>
+ * @brief Returns vector of captured exceptions if any was thrown by the callable.
+ *
+ * Note, can dead lock if notify is never called.
+ */
+inline auto
+getExceptions(WavefrontAlignmentScheduler & me)
+{
+    auto vec = me._exceptionPointers;
+    auto innerExceptions = getExceptions(me._taskScheduler);
+    std::copy(std::begin(innerExceptions), std::end(innerExceptions), std::back_inserter(vec));
+    return vec;
+}
+
+/*
+ * @fn WavefrontAlignmentScheduler#taskScheduler
+ * @headerfile <align_parallel.h>
+ * @brief Returns lvalue reference to the underlying task_scheduler.
+ */
+inline auto&
+taskScheduler(WavefrontAlignmentScheduler & me)
+{
+    return me._taskScheduler;
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_PARALLEL_ALIGNMENT_SCHEDULER_H_
diff --git a/include/seqan/align_parallel/wavefront_alignment_task.h b/include/seqan/align_parallel/wavefront_alignment_task.h
new file mode 100644
index 0000000..f3d4047
--- /dev/null
+++ b/include/seqan/align_parallel/wavefront_alignment_task.h
@@ -0,0 +1,404 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_TASK_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_TASK_H_
+
+namespace seqan
+{
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// Config structre for the execution of one alignment using the wave-front model.
+template <typename TDPSettings>
+struct WavefrontAlignmentTaskConfig
+{
+    // ----------------------------------------------------------------------------
+    // Member Typedefs.
+
+    // DPTrait type forwarding.
+    using TDPTraits       = typename TDPSettings::TTraits;
+    using TScoreValue     = typename Value<typename TDPSettings::TScoringScheme>::Type;
+    using TAlgorithmType  = typename TDPTraits::TAlgorithmType;
+    using TTracebackType  = typename TDPTraits::TTracebackType;
+    using TGapType        = typename TDPTraits::TGapType;
+
+    // Wavefront Alignment Context.
+    using TDPCell         = DPCell_<TScoreValue, TGapType>;
+    using TBufferValue    = Pair<TDPCell, typename TraceBitMap_<>::Type>;
+    using TBuffer         = String<TBufferValue>;
+    using TBlockBuffer    = DPTileBuffer<TBuffer>;
+
+    // DP Execution Context.
+    using TDPProfile      = DPProfile_<TAlgorithmType, TGapType, TTracebackType, Parallel>;
+    using TDPCache        = DPContext<TDPCell, typename TraceBitMap_<>::Type>;
+    using TDPScout        = DPScout_<TDPCell, Default>;
+
+    // Parallel Context.
+    struct IntermediateTraits_
+    {
+        using TScoreValue   = decltype(maxScore(std::declval<TDPScout>()));
+        using THostPosition = decltype(maxHostPosition(std::declval<TDPScout>()));
+    };
+
+    using TDPIntermediate = WavefrontAlignmentResult<IntermediateTraits_>;
+
+    struct AlignThreadLocalConfig_
+    {
+        using TIntermediate = TDPIntermediate;
+        using TCache        = TDPCache;
+
+        using TLocalHost    = std::tuple<TIntermediate, TCache>;
+    };
+
+    using TThreadLocal = WavefrontAlignmentThreadLocalStorage<AlignThreadLocalConfig_>;
+    using TAlignEvent  = WavefrontTaskEvent;
+};
+
+#ifdef SEQAN_SIMD_ENABLED
+template <typename TDPSettings>
+struct WavefrontAlignmentSimdTaskConfig : public WavefrontAlignmentTaskConfig<TDPSettings>
+{
+    // ----------------------------------------------------------------------------
+    // Member Typedefs.
+
+    using TBase_ = WavefrontAlignmentTaskConfig<TDPSettings>;
+
+    using TDPSimdCell        = DPCell_<typename TDPSettings::TScoreValueSimd, typename TBase_::TGapType>;
+    using TDPSimdTraceValue  = typename TraceBitMap_<typename TDPSettings::TScoreValueSimd>::Type;
+
+    using TDPSimdScoreMatrix = String<TDPSimdCell, Alloc<OverAligned>>;
+    using TDPSimdTraceMatrix = String<TDPSimdTraceValue, Alloc<OverAligned>>;
+    using TDPSimdCache       = DPContext<TDPSimdCell, TDPSimdTraceValue, TDPSimdScoreMatrix, TDPSimdTraceMatrix>;
+
+    using TDPScout_          = DPScout_<TDPSimdCell, SimdAlignmentScout<> >;
+    using TDPIntermediate    = WavefrontAlignmentResult<typename TBase_::IntermediateTraits_>;
+
+    // Parallel Context.
+    struct SimdAlignThreadLocalConfig_
+    {
+
+        using TIntermediate = TDPIntermediate;
+        using TCache        = typename TBase_::TDPCache;
+        using TSimdCache    = TDPSimdCache;
+
+        using TLocalHost    = std::tuple<TIntermediate, TCache, TSimdCache>;
+    };
+
+    using TThreadLocal = WavefrontAlignmentThreadLocalStorage<SimdAlignThreadLocalConfig_>;
+    using TAlignEvent  = WavefrontTaskEvent;
+};
+#endif
+
+// Incubator to setup the alignment job.
+template <typename WavefrontAlignmentTaskConfigConcept>
+struct WavefrontAlignmentTaskIncubator
+{
+    using TWatc = WavefrontAlignmentTaskConfigConcept;
+
+    // ----------------------------------------------------------------------------
+    // Function createBlocks()
+    // ----------------------------------------------------------------------------
+
+    template <typename TSeq>
+    static auto createBlocks(TSeq const & seq, size_t const blockSize)
+    {
+        using TIter = typename Iterator<typename Infix<TSeq const>::Type, Standard>::Type;
+        String<Range<TIter>> blocks;
+        resize(blocks, (length(seq) + blockSize - 1) / blockSize, Exact());
+
+        for (unsigned id = 0; id < length(blocks); ++id)
+            blocks[id] = toRange(infix(seq, id * blockSize, _min(length(seq),(id + 1) * blockSize)));
+        return blocks;
+    }
+
+    // ----------------------------------------------------------------------------
+    // Function createBlockBuffer()
+    // ----------------------------------------------------------------------------
+
+    template <typename TSeqHBlocks, typename TSeqVBlovcks, typename TScore>
+    static auto createBlockBuffer(TSeqHBlocks const & seqHBlocks, TSeqVBlovcks const & seqVBlocks, TScore const & score)
+    {
+        using TDPCell = typename TWatc::TDPCell;
+        typename TWatc::TBlockBuffer buffer;
+        resize(buffer.horizontalBuffer, length(seqHBlocks), Exact());
+        resize(buffer.verticalBuffer, length(seqVBlocks), Exact());
+
+        typename TWatc::TBufferValue tmp;
+
+        using TDPMetaColH = DPMetaColumn_<typename TWatc::TDPProfile, MetaColumnDescriptor<DPInnerColumn, FullColumn>>;
+        using TDPMetaColV = DPMetaColumn_<typename TWatc::TDPProfile, MetaColumnDescriptor<DPInitialColumn, FullColumn>>;
+
+        TDPCell dummyCellD;
+        TDPCell dummyCellH;
+        TDPCell dummyCellV;
+        tmp.i2 = _computeScore(tmp.i1, dummyCellD, dummyCellH, dummyCellV,  Nothing(), Nothing(), score,
+                               RecursionDirectionZero(), typename TWatc::TDPProfile());
+        for (auto itH = begin(buffer.horizontalBuffer, Standard());
+             itH != end(buffer.horizontalBuffer, Standard());
+             ++itH)
+        {
+            resize(*itH, length(front(seqHBlocks)), Exact());
+            for (auto it = begin(*itH, Standard()); it != end(*itH, Standard()); ++it)
+            {
+                it->i2 = _computeScore(it->i1, dummyCellD, tmp.i1, dummyCellV, Nothing(), Nothing(), score,
+                                       typename RecursionDirection_<TDPMetaColH, FirstCell>::Type(),
+                                       typename TWatc::TDPProfile());
+                tmp.i1 = it->i1;
+            }
+        }
+        tmp.i1 = decltype(tmp.i1){};
+        tmp.i2 = _computeScore(tmp.i1, dummyCellD, dummyCellH, dummyCellV, Nothing(), Nothing(), score,
+                               RecursionDirectionZero(), typename TWatc::TDPProfile());
+
+        for (auto itV = begin(buffer.verticalBuffer, Standard()); itV != end(buffer.verticalBuffer, Standard()); ++itV)
+        {
+            resize(*itV, length(front(seqVBlocks)) + 1, Exact());
+            auto it = begin(*itV, Standard());
+            it->i2 = tmp.i2;
+            it->i1 = tmp.i1;
+            ++it;
+            for (; it != end(*itV, Standard()); ++it)
+            {
+                it->i2 = _computeScore(it->i1, dummyCellD, dummyCellH, dummyCellV, Nothing(), Nothing(), score,
+                                       typename RecursionDirection_<TDPMetaColV, InnerCell>::Type(),
+                                       typename TWatc::TDPProfile());
+                _setVerticalScoreOfCell(it->i1, _verticalScoreOfCell(dummyCellV));
+                tmp.i1 = it->i1;
+                tmp.i2 = it->i2;  // TODO(rrahn): Move out of loop.
+            }
+        }
+        return buffer;
+    }
+
+    // ----------------------------------------------------------------------------
+    // Function createTaskGraph()
+    // ----------------------------------------------------------------------------
+
+    template <typename TWavefrontTaskContext>
+    static auto createTaskGraph(TWavefrontTaskContext & taskContext)
+    {
+        using TDagTask = WavefrontTask<TWavefrontTaskContext>;
+
+        std::vector<std::vector<std::shared_ptr<TDagTask>>> graph;
+
+        resize(graph, length(taskContext.seqHBlocks));
+        for (int i = length(taskContext.seqHBlocks); --i >= 0;)
+        {
+            resize(graph[i], length(taskContext.seqVBlocks));
+            for (int j = length(taskContext.seqVBlocks); --j >= 0;)
+            {
+                using TSize = decltype(length(taskContext.seqHBlocks));
+                TDagTask * successorRight = (static_cast<TSize>(i + 1) < length(taskContext.seqHBlocks))
+                                                ?  graph[i+1][j].get()
+                                                : nullptr;
+                TDagTask * successorDown  = (static_cast<TSize>(j + 1) < length(taskContext.seqVBlocks))
+                                                ? graph[i][j+1].get()
+                                                : nullptr;
+                graph[i][j] = std::make_shared<TDagTask>(taskContext,
+                                                         std::array<TDagTask*, 2>{{successorRight, successorDown}},
+                                                         static_cast<size_t>(i), static_cast<size_t>(j),
+                                                         static_cast<size_t>(((i > 0) ? 1 : 0) + ((j > 0) ? 1 : 0)),
+                                                         (static_cast<TSize>(i + 1) == length(taskContext.seqHBlocks)),
+                                                         (static_cast<TSize>(j + 1) == length(taskContext.seqVBlocks)));
+            }
+        }
+        return graph;
+    }
+};
+
+// The actual alignment task that is executed by the wave-front model.
+template <typename TSeqH,
+          typename TSeqV,
+          typename TDPSettings,
+          typename TConfig = WavefrontAlignmentTaskConfig<TDPSettings>>
+class WavefrontAlignmentTask
+{
+public:
+
+    using TIncubator    = WavefrontAlignmentTaskIncubator<TConfig>;
+
+    using TSeqHBlocks   = decltype(TIncubator::createBlocks(std::declval<TSeqH>(), std::declval<size_t>()));
+    using TSeqVBlocks   = decltype(TIncubator::createBlocks(std::declval<TSeqV>(), std::declval<size_t>()));
+    using TTileBuffer   = decltype(TIncubator::createBlockBuffer(std::declval<TSeqHBlocks>(),
+                                                                 std::declval<TSeqVBlocks>(),
+                                                                 std::declval<typename TDPSettings::TScoringScheme>()));
+
+    using TTaskContext  = WavefrontAlignmentContext<TSeqHBlocks, TSeqVBlocks, TTileBuffer, TDPSettings>;
+
+    // ----------------------------------------------------------------------------
+    // Member Variables.
+    // ----------------------------------------------------------------------------
+
+    size_t              alignmentId{0};
+    TSeqH const &       seqH;
+    TSeqV const &       seqV;
+    TDPSettings const & dpSettings;
+    size_t              blockSize;
+
+    // ----------------------------------------------------------------------------
+    // Constructors.
+    // ----------------------------------------------------------------------------
+
+    WavefrontAlignmentTask() = delete;
+
+    WavefrontAlignmentTask(TSeqH const & seqH,
+                           TSeqV const & seqV,
+                           TDPSettings const & dpSetting,
+                           size_t const & blockSize) :
+        seqH(seqH),
+        seqV(seqV),
+        dpSettings(dpSetting),
+        blockSize(blockSize)
+    {}
+
+
+    WavefrontAlignmentTask(size_t const id,
+                           TSeqH const & seqH,
+                           TSeqV const & seqV,
+                           TDPSettings const & dpSetting,
+                           size_t const & blockSize) :
+        alignmentId(id),
+        seqH(seqH),
+        seqV(seqV),
+        dpSettings(dpSetting),
+        blockSize(blockSize)
+    {}
+
+    // ----------------------------------------------------------------------------
+    // Member Functions.
+    // ----------------------------------------------------------------------------
+
+    // This function now run's in a separate thread.
+    template <typename TWavefrontExecutor,
+              typename TCallback>
+    inline void
+    operator()(uint16_t const instanceId,
+               TWavefrontExecutor & executor,
+               TCallback && callback)
+    {
+        // Initialize the strings.
+        auto seqHBlocks = TIncubator::createBlocks(seqH, blockSize);
+        auto seqVBlocks = TIncubator::createBlocks(seqV, blockSize);
+
+        // Create the buffer for the matrix.
+        auto buffer = TIncubator::createBlockBuffer(seqHBlocks, seqVBlocks, dpSettings.scoringScheme);
+
+        // Setup the task context and create task graph.
+        TTaskContext taskContext{instanceId, seqHBlocks, seqVBlocks, buffer, dpSettings};
+        auto taskGraph = TIncubator::createTaskGraph(taskContext);
+
+        // Prepare event.
+        WavefrontTaskEvent event;
+        context(*taskGraph.back().back()).ptrEvent = &event;
+
+        // Kick off the execution.
+        using TWavefrontTaskExec = WavefrontTaskExecutor<std::decay_t<decltype(*taskGraph[0][0])>, TWavefrontExecutor>;
+        spawn(executor, TWavefrontTaskExec{taskGraph[0][0].get(), &executor});
+
+        // Wait for alignment to finish.
+        wait(event);
+
+        // Reduce.
+        typename TConfig::TDPIntermediate interMax{};
+        auto collectAndReset = [&](auto & threadLocalStorage)
+        {
+            updateMax(interMax, intermediate(threadLocalStorage, instanceId));
+            clear(intermediate(threadLocalStorage, instanceId));
+        };
+        combineEach(*executor.ptrThreadLocal, collectAndReset);
+        // Continue execution.
+        callback(alignmentId, interMax._maxState.first);
+    }
+
+    template <typename TWavefrontExecutor,
+              typename TSimdTaskQueue,
+              typename TCallback>
+    inline void
+    operator()(uint16_t const instanceId,
+               TWavefrontExecutor & executor,
+               TSimdTaskQueue & taskQueue,
+               TCallback && callback)
+    {
+        // Initialize the strings.
+        auto seqHBlocks = TIncubator::createBlocks(seqH, blockSize);
+        auto seqVBlocks = TIncubator::createBlocks(seqV, blockSize);
+
+        // Create the buffer for the matrix.
+        auto buffer = TIncubator::createBlockBuffer(seqHBlocks, seqVBlocks, dpSettings.scoringScheme);
+
+        // Setup the task context and create task graph.
+        TTaskContext taskContext{instanceId, seqHBlocks, seqVBlocks, buffer, dpSettings};
+        auto taskGraph = TIncubator::createTaskGraph(taskContext);
+
+        // Prepare event.
+        WavefrontTaskEvent event;
+        context(*taskGraph.back().back()).ptrEvent = &event;
+
+        // Kick off the execution.
+        using TWavefrontTaskExec = WavefrontTaskExecutor<TSimdTaskQueue, TWavefrontExecutor>;
+        appendValue(taskQueue, *taskGraph[0][0]);
+        spawn(executor, TWavefrontTaskExec{&taskQueue, &executor});
+
+        // Wait for alignment to finish.
+        wait(event);
+
+        // Reduce.
+        typename TConfig::TDPIntermediate interMax{};
+        auto collectAndReset = [&](auto & threadLocalStorage)
+        {
+            updateMax(interMax, intermediate(threadLocalStorage, instanceId));
+            clear(intermediate(threadLocalStorage, instanceId));
+        };
+        combineEach(*executor.ptrThreadLocal, collectAndReset);
+        callback(alignmentId, interMax._maxState.first);
+    }
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_ALIGNMENT_TASK_H_
diff --git a/include/seqan/align_parallel/wavefront_alignment_thread_local_storage.h b/include/seqan/align_parallel/wavefront_alignment_thread_local_storage.h
new file mode 100644
index 0000000..6cda1c1
--- /dev/null
+++ b/include/seqan/align_parallel/wavefront_alignment_thread_local_storage.h
@@ -0,0 +1,130 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_ALIGN_PARALLEL_DP_THREAD_LOCAL_STORAGE_H_
+#define SEQAN_INCLUDE_ALIGN_PARALLEL_DP_THREAD_LOCAL_STORAGE_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// Shared thread local storage for the parallel alignment instances.
+template <typename TConfig>
+class WavefrontAlignmentThreadLocalStorage
+{
+public:
+    //-------------------------------------------------------------------------
+    // Member Types.
+
+    using TAlignmentLocal = typename TConfig::TLocalHost;
+
+    //-------------------------------------------------------------------------
+    // Private Members.
+
+    std::vector<TAlignmentLocal>   _multiAlignmentThreadLocal;
+
+    //-------------------------------------------------------------------------
+    // Constructor.
+
+    explicit WavefrontAlignmentThreadLocalStorage(size_t const numAlignments) :
+        _multiAlignmentThreadLocal(numAlignments)
+    {}
+
+    // Delegating default constructor.
+    WavefrontAlignmentThreadLocalStorage() : WavefrontAlignmentThreadLocalStorage(1)
+    {}
+
+    WavefrontAlignmentThreadLocalStorage(WavefrontAlignmentThreadLocalStorage const &) = default;
+    WavefrontAlignmentThreadLocalStorage(WavefrontAlignmentThreadLocalStorage &&) = default;
+
+    //-------------------------------------------------------------------------
+    // Destructor.
+
+    ~WavefrontAlignmentThreadLocalStorage() = default;
+
+    //-------------------------------------------------------------------------
+    // Member Functions.
+
+    WavefrontAlignmentThreadLocalStorage& operator=(WavefrontAlignmentThreadLocalStorage const &) = default;
+    WavefrontAlignmentThreadLocalStorage& operator=(WavefrontAlignmentThreadLocalStorage &&) = default;
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// Gets the intermediate result for the specific alignment job.
+template <typename TConfig>
+inline typename TConfig::TIntermediate &
+intermediate(WavefrontAlignmentThreadLocalStorage<TConfig> & me,
+             size_t const alignId)
+{
+    SEQAN_ASSERT_LT(alignId, me._multiAlignmentThreadLocal.size());
+    return std::get<typename TConfig::TIntermediate>(me._multiAlignmentThreadLocal[alignId]);
+}
+
+// Gets the chache for the specific alignment job.
+template <typename TConfig>
+inline typename TConfig::TCache &
+cache(WavefrontAlignmentThreadLocalStorage<TConfig> & me,
+      size_t const alignId)
+{
+    SEQAN_ASSERT_LT(alignId, me._multiAlignmentThreadLocal.size());
+    return std::get<typename TConfig::TCache>(me._multiAlignmentThreadLocal[alignId]);
+}
+
+// Gets the simd chache for the specific alignment job.
+template <typename TConfig>
+inline typename TConfig::TSimdCache &
+simdCache(WavefrontAlignmentThreadLocalStorage<TConfig> & me,
+          size_t const alignId)
+{
+    SEQAN_ASSERT_LT(alignId, me._multiAlignmentThreadLocal.size());
+    return std::get<typename TConfig::TSimdCache>(me._multiAlignmentThreadLocal[alignId]);
+}
+
+}  // namespace seqan
+
+#endif  // SEQAN_INCLUDE_ALIGN_PARALLEL_DP_THREAD_LOCAL_STORAGE_H_
diff --git a/include/seqan/align_parallel/wavefront_task.h b/include/seqan/align_parallel/wavefront_task.h
new file mode 100644
index 0000000..a832334
--- /dev/null
+++ b/include/seqan/align_parallel/wavefront_task.h
@@ -0,0 +1,365 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_H_
+
+namespace seqan
+{
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// Context used per task. Access information like the infixes of the sequences for this block and other.
+template <typename TSeqHBlocks,
+          typename TSeqVBlocks,
+          typename TTileBuffer,
+          typename TDPSettings,
+          typename TEvent = WavefrontTaskEvent>
+struct WavefrontAlignmentContext
+{
+    size_t              alignmentId{0};
+    TSeqHBlocks const & seqHBlocks;
+    TSeqVBlocks const & seqVBlocks;
+    TTileBuffer       & tileBuffer;
+    TDPSettings const & dpSettings;
+    TEvent            * ptrEvent{nullptr};
+
+    //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type.
+    WavefrontAlignmentContext(size_t const _alignmentId,
+                              TSeqHBlocks const & _seqHBlocks,
+                              TSeqVBlocks const & _seqVBlocks,
+                              TTileBuffer       & _tileBuffer,
+                              TDPSettings const & _dpSettings) :
+        alignmentId(_alignmentId),
+        seqHBlocks(_seqHBlocks),
+        seqVBlocks(_seqVBlocks),
+        tileBuffer(_tileBuffer),
+        dpSettings(_dpSettings)
+    {}
+};
+
+// The abstract task that is executed as separat alignment instance.
+template <typename TAlignmentContext>
+class WavefrontTask
+{
+public:
+
+    using TContext  = TAlignmentContext;
+
+    TContext &                     context;
+    std::array<WavefrontTask*, 2>  successor{{nullptr, nullptr}};
+    size_t                         col{0};
+    size_t                         row{0};
+    std::atomic<size_t>            refCount{0};
+    bool                           lastTileH{false};
+    bool                           lastTileV{false};
+
+
+    //-------------------------------------------------------------------------
+    // Constructor
+    WavefrontTask() = delete;
+
+    WavefrontTask(TContext & context, std::array<WavefrontTask*, 2> successor,
+                  size_t const col,
+                  size_t const row,
+                  size_t const refCount,
+                  bool const lastTileH,
+                  bool const lastTileV) :
+        context(context),
+        successor(std::move(successor)),
+        col(col), row(row),
+        refCount(refCount),
+        lastTileH(lastTileH), lastTileV(lastTileV)
+    {}
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template <typename TContext>
+struct TaskExecutionTraits;
+
+template <typename ...TArgs>
+struct TaskExecutionTraits<WavefrontAlignmentContext<TArgs...>>
+{
+    using TaskContext_      = WavefrontAlignmentContext<TArgs...>;
+
+    using TSeqHBlocks       = typename std::decay<decltype(std::declval<TaskContext_>().seqHBlocks)>::type;
+    using TSeqVBlocks       = typename std::decay<decltype(std::declval<TaskContext_>().seqVBlocks)>::type;
+    using TWavefrontBuffer  = typename std::decay<decltype(std::declval<TaskContext_>().tileBuffer)>::type;
+    using TDPSettings       = typename std::decay<decltype(std::declval<TaskContext_>().dpSettings)>::type;
+
+    using TTileBuffer       = typename std::decay<decltype(std::declval<TWavefrontBuffer>().horizontalBuffer[0])>::type;
+    using TDPScoutState     = DPScoutState_<DPTiled<TTileBuffer>>;
+
+    // Sequence types.
+    using TSeqH = typename Value<TSeqHBlocks>::Type;
+    using TSeqV = typename Value<TSeqVBlocks>::Type;
+
+    // DPTrait type forwarding.
+    using TDPTraits         = typename TDPSettings::TTraits;
+    using TScoreValue       = typename Value<typename TDPSettings::TScoringScheme>::Type;
+    using TAlgorithmType    = typename TDPTraits::TAlgorithmType;
+    using TTracebackType    = typename TDPTraits::TTracebackType;
+    using TGapType          = typename TDPTraits::TGapType;
+
+    // Wavefront Alignment Context.
+    using TDPCell           = DPCell_<TScoreValue, TGapType>;
+
+    using TScoutSpec        = typename ScoutSpecForAlignmentAlgorithm_<TAlgorithmType, TDPScoutState>::Type;
+    using TDPScout          = DPScout_<TDPCell, TScoutSpec>;
+};
+
+template <typename TWavefrontAlignmentContextConcept>
+struct SimdTaskExecutionTraits : public TaskExecutionTraits<TWavefrontAlignmentContextConcept>
+{
+    using TBase = TaskExecutionTraits<TWavefrontAlignmentContextConcept>;
+
+    using TScoreValue = typename TBase::TDPSettings::TScoreValueSimd;
+    using TDPCell     = DPCell_<TScoreValue, typename TBase::TGapType>;
+    using TTraceValue = typename TraceBitMap_<TScoreValue>::Type;
+    using TBufferValue = Pair<TDPCell, TTraceValue>;
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+template <typename ...TArgs>
+inline void
+setRefCount(WavefrontTask<TArgs...> & me, size_t const count)
+{
+    me.refCount.store(count, std::memory_order_relaxed);
+}
+
+template <typename ...TArgs>
+inline unsigned
+decrementRefCount(WavefrontTask<TArgs...> & me)
+{
+    return --me.refCount;
+}
+
+template <typename ...TArgs>
+inline unsigned
+incrementRefCount(WavefrontTask<TArgs...> & me)
+{
+    return ++me.refCount;
+}
+
+template <typename TTask>
+inline auto
+column(TTask const & task) -> decltype(task.col)
+{
+    return task.col;
+}
+
+template <typename TTask>
+inline auto
+row(TTask const & task) -> decltype(task.row)
+{
+    return task.row;
+}
+
+template <typename TTask>
+inline bool
+inLastColumn(TTask const & task)
+{
+    return task.lastTileH;
+}
+
+template <typename TTask>
+inline bool
+inLastRow(TTask const & task)
+{
+    return task.lastTileV;
+}
+
+template <typename TTask>
+inline bool
+isLastTask(TTask const & task)
+{
+    return inLastColumn(task) && inLastRow(task);
+}
+
+template <typename TTask>
+inline auto
+successor(TTask & task) -> std::add_lvalue_reference_t<decltype(task.successor)>
+{
+    return task.successor;
+}
+
+template <typename TTask>
+inline auto
+successor(TTask const & task) -> std::add_lvalue_reference_t<std::add_const_t<decltype(task.successor)>>
+{
+    return task.successor;
+}
+
+template <typename TTask>
+inline auto
+context(TTask & task) -> std::add_lvalue_reference_t<decltype(task.context)>
+{
+    return task.context;
+}
+
+template <typename TTask>
+inline auto
+context(TTask const & task) -> std::add_lvalue_reference_t<std::add_const_t<decltype(task.context)>>
+{
+    return task.context;
+}
+
+template <typename TAlgorithm, typename TTask>
+inline bool
+isTrackTile(TTask const & task)
+{
+    return isLastColumn(task) && isLastRow(task);
+}
+
+template <typename TTask>
+inline bool
+isTrackTile(TTask const & task)
+{
+    return isLastColumn(task) && isLastRow(task);
+}
+
+template <typename TTask, typename TDPLocalData>
+inline void
+executeScalar(TTask & task, TDPLocalData & dpLocal)
+{
+    using TExecTraits = TaskExecutionTraits<typename TTask::TContext>;
+
+    auto & taskContext = context(task);
+    // Load the cache from the local data.
+    auto & dpCache = cache(dpLocal, taskContext.alignmentId);
+    auto & buffer = taskContext.tileBuffer;
+
+    // Capture the buffer.
+    typename TExecTraits::TDPScoutState scoutState(buffer.horizontalBuffer[column(task)],
+                                                   buffer.verticalBuffer[row(task)]);  // Task local
+
+    typename TExecTraits::TDPScout scout(scoutState);
+
+    impl::computeTile(dpCache, scout,
+                      taskContext.seqHBlocks[column(task)],
+                      taskContext.seqVBlocks[row(task)],
+                      taskContext.dpSettings.scoringScheme,
+                      taskContext.dpSettings);
+    // We want to get the state here from the scout.
+    if(impl::AlgorithmProperty<typename TExecTraits::TAlgorithmType>::isTrackingEnabled(task))
+    {
+        // TODO(rrahn): Implement the interface.
+        // TODO(rrahn): Make it a member function of a policy so that we don't have to implement the specifics here
+        updateMax(intermediate(dpLocal, taskContext.alignmentId),
+                  {maxScore(scout), maxHostPosition(scout)},
+                  column(task),
+                  row(task));
+    }
+}
+
+template <typename TBuffer>
+inline void
+printSimdBuffer(TBuffer const & buffer, size_t const l)
+{
+    for (auto simdHolder : buffer)
+    {
+        std::cout << "<";
+        unsigned i = 0;
+        for (; i < l - 1; ++i)
+        {
+            std::cout << simdHolder.i1._score[i] << ", ";
+        }
+        std::cout << simdHolder.i1._score[i] << ">\n";
+    }
+}
+
+#ifdef SEQAN_SIMD_ENABLED
+template <typename TTasks, typename TDPLocalData>
+inline void
+executeSimd(TTasks & tasks, TDPLocalData & dpLocal)
+{
+    using TTask = typename std::remove_pointer<typename Value<TTasks>::Type>::type;
+    using TExecTraits = SimdTaskExecutionTraits<typename TTask::TContext>;
+
+    auto offset = impl::computeOffset(tasks, TExecTraits{});
+    // Has to be adapted to take the correct buffer from the corresponding task.
+    auto simdBufferH = impl::gatherSimdBuffer(tasks,
+                                              [] (auto & task)
+                                              {
+                                                  return &context(task).tileBuffer.horizontalBuffer[column(task)];
+                                              },
+                                              offset,
+                                              TExecTraits{});
+    auto simdBufferV = impl::gatherSimdBuffer(tasks,
+                                              [] (auto & task)
+                                              {
+                                                  return &context(task).tileBuffer.verticalBuffer[row(task)];
+                                              },
+                                              offset,
+                                              TExecTraits{});
+
+    // Does not really make sense.
+    auto & cache = simdCache(dpLocal, 0);
+    // Run alignment.
+    impl::computeSimdBatch(cache, simdBufferH, simdBufferV, tasks, dpLocal, offset, TExecTraits{});
+
+    // Write back into buffer.
+    impl::scatterSimdBuffer(tasks,
+                            simdBufferH,
+                            [](auto & task)
+                            {
+                                return &context(task).tileBuffer.horizontalBuffer[column(task)];
+                            },
+                            offset,
+                            TExecTraits{});
+    impl::scatterSimdBuffer(tasks,
+                            simdBufferV,
+                            [](auto & task)
+                            {
+                                return &context(task).tileBuffer.verticalBuffer[row(task)];
+                            },
+                            offset,
+                            TExecTraits{});
+}
+#endif  // SEQAN_SIMD_ENABLED
+
+}  // namespace seqan
+
+#endif  // INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_H_
diff --git a/include/seqan/parallel/parallel_tags.h b/include/seqan/align_parallel/wavefront_task_event.h
similarity index 59%
copy from include/seqan/parallel/parallel_tags.h
copy to include/seqan/align_parallel/wavefront_task_event.h
index 20d395c..71dfd6e 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/include/seqan/align_parallel/wavefront_task_event.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
@@ -29,15 +29,14 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tags to select serial/parallel algorithms.
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
-#define SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EVENT_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EVENT_H_
 
-namespace seqan {
+namespace seqan
+{
 
 // ============================================================================
 // Forwards
@@ -47,40 +46,59 @@ namespace seqan {
 // Tags, Classes, Enums
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Tag Parallel
-// ----------------------------------------------------------------------------
+// Event to signal end of one alignment instance.
+class WavefrontTaskEvent
+{
+public:
+    std::mutex                  mutexLastTask{};
+    std::condition_variable     conditionLastTask{};
+    bool                        readyLastTask{false};
+
+    WavefrontTaskEvent() = default;
+
+    WavefrontTaskEvent(WavefrontTaskEvent const &) = delete;
+    WavefrontTaskEvent(WavefrontTaskEvent &&) = delete;
 
-/*!
- * @defgroup ParallelismTags Parallelism Tags
- * @brief Tags for enabling/disabling parallelism.
- *
- * @tag ParallelismTags#Parallel
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the parallel implementation of an algorithm.
- *
- * @tag ParallelismTags#Serial
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the serial implementation of an algorithm.
- */
+    WavefrontTaskEvent& operator=(WavefrontTaskEvent const &) = delete;
+    WavefrontTaskEvent& operator=(WavefrontTaskEvent &&) = delete;
 
-struct Parallel_;
-typedef Tag<Parallel_> Parallel;
+    ~WavefrontTaskEvent()
+    {
+        if (!readyLastTask)
+        {
+            {
+                std::lock_guard<decltype(mutexLastTask)> lck(mutexLastTask);
+                readyLastTask = true;
+            }
+            conditionLastTask.notify_one();
+        }
+    }
+};
 
 // ============================================================================
 // Metafunctions
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Metafunction DefaultParallelSpec
-// ----------------------------------------------------------------------------
+// ============================================================================
+// Functions
+// ============================================================================
 
-template <typename TObject>
-struct DefaultParallelSpec
+inline void
+notify(WavefrontTaskEvent & event)
 {
-    typedef Parallel Type;
-};
+    std::lock_guard<decltype(event.mutexLastTask)> lck(event.mutexLastTask);
+    event.readyLastTask = true;
+    event.conditionLastTask.notify_one();  // We require a strict synchronization between waiting and notifying thread.
+}
+
+inline void
+wait(WavefrontTaskEvent & event)
+{
+    std::unique_lock<decltype(event.mutexLastTask)> lck(event.mutexLastTask);
+    if (!event.readyLastTask)
+        event.conditionLastTask.wait(lck, [&] { return event.readyLastTask; });
+}
 
 }  // namespace seqan
 
-#endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EVENT_H_
diff --git a/include/seqan/align_parallel/wavefront_task_executor.h b/include/seqan/align_parallel/wavefront_task_executor.h
new file mode 100644
index 0000000..e9df523
--- /dev/null
+++ b/include/seqan/align_parallel/wavefront_task_executor.h
@@ -0,0 +1,146 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EXECUTOR_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EXECUTOR_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+template <typename TResource>
+struct WavefrontTaskExecutionPolicy;
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// Task executor. Manages the execution of single alignment blocks.
+template <typename TResource, typename TWavefrontExecutor>
+struct WavefrontTaskExecutor
+{
+    TResource*            _ptrResource{nullptr};
+    TWavefrontExecutor *  _ptrWavefrontExecutor{nullptr};
+
+    //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type.
+    WavefrontTaskExecutor() = default;
+
+    WavefrontTaskExecutor(TResource * _resource,
+                          TWavefrontExecutor * _wavefrontExecutor) :
+            _ptrResource{_resource},
+            _ptrWavefrontExecutor(_wavefrontExecutor)
+    {}
+
+    inline void operator()()
+    {
+        WavefrontTaskExecutionPolicy<TResource>::execute(*_ptrResource, *_ptrWavefrontExecutor);
+    }
+};
+
+// Policy for no SIMD execution.
+template <typename ...TArgs>
+struct WavefrontTaskExecutionPolicy<WavefrontTask<TArgs...>>
+{
+
+    template <typename TResource, typename TWavefrontExecutor>
+    inline static void
+    execute(TResource & task, TWavefrontExecutor & wavefrontExec)
+    {
+        using TWaveTaskExec = WavefrontTaskExecutor<TResource, TWavefrontExecutor>;
+
+        executeScalar(task, local(wavefrontExec));
+        for (auto succ : successor(task))
+        {
+            if (succ && decrementRefCount(*succ) == 0)
+                spawn(wavefrontExec, TWaveTaskExec{succ, &wavefrontExec});
+        }
+        if (isLastTask(task))
+        {
+            notify(*(context(task).ptrEvent));
+        }
+    }
+};
+
+// Policy for SIMD execution.
+template <typename TValue, size_t VECTOR_SIZE>
+struct WavefrontTaskExecutionPolicy<WavefrontTaskQueue<TValue, VECTOR_SIZE>>
+{
+    template <typename TResource, typename TWavefrontExecutor>
+    inline static void
+    execute(TResource & resource, TWavefrontExecutor & wavefrontExec)
+    {
+        using TWaveTaskExec = WavefrontTaskExecutor<TResource, TWavefrontExecutor>;
+
+        typename TResource::ResultType tasks;
+        if (!tryPopTasks(tasks, resource))
+            return;
+
+        SEQAN_ASSERT(!empty(tasks));
+        if (tasks.size()  == 1)
+            executeScalar(*front(tasks), local(wavefrontExec));
+        else
+            executeSimd(tasks, local(wavefrontExec));
+
+        for (auto task : tasks)
+        {
+            for (auto succ : successor(*task))
+            {
+                if (succ && decrementRefCount(*succ) == 0)
+                {
+                    appendValue(resource, *succ);
+                    spawn(wavefrontExec, TWaveTaskExec{&resource, &wavefrontExec});
+                }
+            }
+            if (isLastTask(*task))
+            {
+                notify(*(context(*task).ptrEvent));
+            }
+        }
+    }
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_EXECUTOR_H_
diff --git a/include/seqan/parallel/parallel_tags.h b/include/seqan/align_parallel/wavefront_task_queue.h
similarity index 51%
copy from include/seqan/parallel/parallel_tags.h
copy to include/seqan/align_parallel/wavefront_task_queue.h
index 20d395c..811594f 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/include/seqan/align_parallel/wavefront_task_queue.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
@@ -29,15 +29,14 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tags to select serial/parallel algorithms.
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
-#define SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_WAVEFRONT_TASK_QUEUE_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_DP_WAVEFRONT_TASK_QUEUE_H_
 
-namespace seqan {
+namespace seqan
+{
 
 // ============================================================================
 // Forwards
@@ -47,40 +46,94 @@ namespace seqan {
 // Tags, Classes, Enums
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Tag Parallel
-// ----------------------------------------------------------------------------
-
-/*!
- * @defgroup ParallelismTags Parallelism Tags
- * @brief Tags for enabling/disabling parallelism.
- *
- * @tag ParallelismTags#Parallel
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the parallel implementation of an algorithm.
- *
- * @tag ParallelismTags#Serial
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the serial implementation of an algorithm.
- */
-
-struct Parallel_;
-typedef Tag<Parallel_> Parallel;
+// Central task queue used in simd mode to gather multiple blocks to gather full simd registers.
+template <typename TValue,
+          size_t VECTOR_SIZE_>
+class WavefrontTaskQueue
+{
+public:
+
+
+    // Member Types.
+    using TQueue = ConcurrentQueue<TValue*>;
+    using ResultType = std::vector<TValue*>;
+    using ValueType = TValue;
+
+    // Members.
+    static constexpr size_t VECTOR_SIZE{VECTOR_SIZE_};
+
+    TQueue      queue;
+    std::mutex  mutexPopQueue;
+    bool        hasNotified{false};
+
+    // Constructors.
+    WavefrontTaskQueue()
+    {
+        lockWriting(queue);
+        lockReading(queue);
+    }
+
+    WavefrontTaskQueue(WavefrontTaskQueue const&) = delete;
+    WavefrontTaskQueue(WavefrontTaskQueue &&) = delete;
+
+    WavefrontTaskQueue& operator=(WavefrontTaskQueue const &) = delete;
+    WavefrontTaskQueue& operator=(WavefrontTaskQueue &&) = delete;
+
+    ~WavefrontTaskQueue()
+    {
+        if (!hasNotified)
+            unlockWriting(queue);
+        unlockReading(queue);
+    }
+};
 
 // ============================================================================
 // Metafunctions
 // ============================================================================
 
-// ----------------------------------------------------------------------------
-// Metafunction DefaultParallelSpec
-// ----------------------------------------------------------------------------
+// ============================================================================
+// Functions
+// ============================================================================
 
-template <typename TObject>
-struct DefaultParallelSpec
+template <typename TValue, size_t VECTOR_SIZE>
+inline bool
+tryPopTasks(typename WavefrontTaskQueue<TValue, VECTOR_SIZE>::ResultType & tasks,
+            WavefrontTaskQueue<TValue, VECTOR_SIZE> & me)
 {
-    typedef Parallel Type;
-};
+    clear(tasks);
+    std::lock_guard<std::mutex> lck(me.mutexPopQueue);
+    if (length(me.queue) < WavefrontTaskQueue<TValue, VECTOR_SIZE>::VECTOR_SIZE)
+    {
+        resize(tasks, 1);
+        if (!popFront(tasks[0], me.queue, Serial()))
+        {
+            return false;
+        }
+    }
+    else
+    {
+        for (size_t lane = 0u; lane < VECTOR_SIZE; ++lane)
+            tasks.push_back(popFront(me.queue, Serial()));
+    }
+    return true;
+}
+
+template <typename TValue, size_t VECTOR_SIZE>
+inline void
+appendValue(WavefrontTaskQueue<TValue, VECTOR_SIZE> & me,
+            TValue & newTask)
+{
+    appendValue(me.queue, &newTask);
+}
+
+template <typename TValue, size_t VECTOR_SIZE>
+inline void
+notify(WavefrontTaskQueue<TValue, VECTOR_SIZE> & me)
+{
+    me.hasNotified = true;
+    unlockWriting(me.queue);
+}
 
 }  // namespace seqan
 
-#endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_DP_WAVEFRONT_TASK_QUEUE_H_
diff --git a/include/seqan/align_parallel/wavefront_task_scheduler.h b/include/seqan/align_parallel/wavefront_task_scheduler.h
new file mode 100644
index 0000000..9084a76
--- /dev/null
+++ b/include/seqan/align_parallel/wavefront_task_scheduler.h
@@ -0,0 +1,218 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_SCHEDULER_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_SCHEDULER_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// Scheduler for wavefront tasks.
+class WavefrontTaskScheduler
+{
+public:
+
+    //-------------------------------------------------------------------------
+    // Memeber Types
+
+    using TWrapper = std::function<void()>;
+    using TTaskQueue = ConcurrentQueue<TWrapper>;
+
+    //-------------------------------------------------------------------------
+    // Member Variables
+
+    ThreadPool  _threadPool;
+    TTaskQueue  _taskQueue;
+
+    unsigned    _writerCount;
+
+    std::mutex                      _mutexPushException;
+    std::vector<std::exception_ptr> _exceptionPointers;
+    std::atomic<bool>               _isValid{true};
+
+    std::function<void()> job = [this] ()
+    {
+        lockReading(_taskQueue);
+        waitForFirstValue(_taskQueue);  // Wait for all writers to be setup.
+
+        std::function<void()> _dummy = [] ()
+        {  // TODO(rrahn): Could throw exception to signal something went terribly wrong.
+            SEQAN_ASSERT_FAIL("Trying to exceute empty wavefront task in a thread");
+        };
+        TWrapper task{_dummy};
+
+        while (true)
+        {
+            if (!popFront(task, _taskQueue))
+                break;  // Empty queue and no writer registered.
+
+            try
+            {
+                task();  // Execute the task;
+            }
+            catch (...)
+            {  // Catch exception, and signal failure. Continue running until queue is empty.
+                {
+                    std::lock_guard<std::mutex> lck(_mutexPushException);
+                    _exceptionPointers.push_back(std::current_exception());
+                }
+                _isValid.store(false, std::memory_order_release);
+            }
+        }
+        unlockReading(_taskQueue);
+    };
+
+    //-------------------------------------------------------------------------
+    // Constructor
+
+    WavefrontTaskScheduler(size_t const threadCount, size_t const writerCount) :
+        _writerCount(writerCount)
+    {
+
+        for (unsigned i = 0; i < threadCount; ++i)
+        {
+            spawn(_threadPool, job);
+        }
+        setCpuAffinity(_threadPool, 0, 1);
+    }
+
+    WavefrontTaskScheduler(size_t const threadCount) : WavefrontTaskScheduler(threadCount, 0)
+    {}
+
+    WavefrontTaskScheduler(WavefrontTaskScheduler const &) = delete;
+    WavefrontTaskScheduler(WavefrontTaskScheduler &&) = delete;
+
+    //-------------------------------------------------------------------------
+    // Member Functions
+
+    WavefrontTaskScheduler& operator=(WavefrontTaskScheduler const &) = delete;
+    WavefrontTaskScheduler& operator=(WavefrontTaskScheduler &&) = delete;
+
+    //-------------------------------------------------------------------------
+    // Destructor
+
+    ~WavefrontTaskScheduler()
+    {}
+    // In destructor of thread pool we wait for the outstanding alignments to be finished
+    // and then continue destruction of the remaining members and cleaning up the stack.
+    // Note the number of writers must be set to 0, for the queue to stop spinning.
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+template <typename TScheduler>
+struct SchedulerTraits;
+
+template <>
+struct SchedulerTraits<WavefrontTaskScheduler>
+{
+    using TWrapper_ = typename WavefrontTaskScheduler::TWrapper;
+    using TTask  = TWrapper_;
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+inline void
+setWriterCount(WavefrontTaskScheduler & me, size_t const count) noexcept
+{
+    me._writerCount = count;
+}
+
+inline void
+lockWriting(WavefrontTaskScheduler & me) noexcept
+{
+    lockWriting(me._taskQueue);
+}
+
+inline void
+unlockWriting(WavefrontTaskScheduler & me) noexcept
+{
+    unlockWriting(me._taskQueue);
+}
+
+inline void
+waitForWriters(WavefrontTaskScheduler & me) noexcept
+{
+    waitForWriters(me._taskQueue, me._writerCount);
+}
+
+inline bool
+isValid(WavefrontTaskScheduler & me) noexcept
+{
+    return me._isValid.load(std::memory_order_acquire);
+}
+
+inline void
+scheduleTask(WavefrontTaskScheduler & me,
+             typename SchedulerTraits<WavefrontTaskScheduler>::TTask task)
+{
+    if (!isValid(me))
+    {  // TODO(rrahn): Improve error handling.
+        throw std::runtime_error("Invalid Task Scheduler");
+    }
+    appendValue(me._taskQueue, std::move(task));
+}
+
+inline void
+wait(WavefrontTaskScheduler & me)
+{
+    SEQAN_ASSERT(me._taskQueue.writerCount == 0);
+
+    join(me._threadPool);
+
+    SEQAN_ASSERT(empty(me._taskQueue));
+    SEQAN_ASSERT(me._taskQueue.readerCount == 0);
+}
+
+inline auto
+getExceptions(WavefrontTaskScheduler & me)
+{
+    return me._exceptionPointers;
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_SCHEDULER_H_
diff --git a/include/seqan/align_parallel/wavefront_task_util.h b/include/seqan/align_parallel/wavefront_task_util.h
new file mode 100644
index 0000000..30a33dd
--- /dev/null
+++ b/include/seqan/align_parallel/wavefront_task_util.h
@@ -0,0 +1,557 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_UTIL_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_UTIL_H_
+
+namespace seqan
+{
+namespace impl
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// Helper meta-function to extract the correct DP Property.
+template <typename TAlgotrithm>
+struct AlgorithmProperty
+{
+    template <typename TTask>
+    inline static bool
+    isTrackingEnabled(TTask const & tile)
+    {
+        return isLastColumn(tile) && isLastRow(tile);
+    }
+};
+
+template <typename TFreeEndGaps>
+struct AlgorithmProperty<GlobalAlignment_<TFreeEndGaps>>
+{
+    template <typename TTask>
+    inline static bool
+    isTrackingEnabled(TTask const & tile)
+    {
+        return (IsFreeEndGap_<TFreeEndGaps, DPLastColumn>::VALUE && inLastColumn(tile)) ||
+               (IsFreeEndGap_<TFreeEndGaps, DPLastRow>::VALUE && inLastRow(tile)) ||
+               (inLastColumn(tile) && inLastRow(tile));
+    }
+};
+
+template <typename TSpec>
+struct AlgorithmProperty<LocalAlignment_<TSpec>>
+{
+    template <typename TTask>
+    inline static bool
+    isTrackingEnabled(TTask const & /*tile*/)
+    {
+        return true;
+    }
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Function computeTile()
+// ----------------------------------------------------------------------------
+
+// Wrapper function to call alignment core for the specific block.
+template <typename TScoreValue, typename TTraceValue, typename TScoreMatHost, typename TTraceMatHost,
+          typename TDPScout,
+          typename TSequenceH,
+          typename TSequenceV,
+          typename TScoringScheme,
+          typename TDPSettings>
+inline void
+computeTile(DPContext<TScoreValue, TTraceValue, TScoreMatHost, TTraceMatHost> & dpContext,
+            TDPScout & scout,
+            TSequenceH const & seqH,
+            TSequenceV const & seqV,
+            TScoringScheme const & scoringScheme,
+            TDPSettings const & /*settings*/)
+{
+    using TDPTraits = typename TDPSettings::TTraits;
+
+    using TScoreMatrixSpec = typename DefaultScoreMatrixSpec_<typename TDPTraits::TAlgorithmType>::Type;
+
+    using TDPScoreMatrix = DPMatrix_<TScoreValue, TScoreMatrixSpec, TScoreMatHost>;
+    using TDPTraceMatrix = DPMatrix_<TTraceValue, FullDPMatrix, TTraceMatHost>;
+
+    using TDPScoreMatrixNavigator = DPMatrixNavigator_<TDPScoreMatrix, DPScoreMatrix, NavigateColumnWise>;
+    using TDPTraceMatrixNavigator = DPMatrixNavigator_<TDPTraceMatrix, DPTraceMatrix<typename TDPTraits::TTracebackType>, NavigateColumnWise>;
+
+    using TDPProfile = DPProfile_<typename TDPTraits::TAlgorithmType,
+                                  typename TDPTraits::TGapType,
+                                  typename TDPTraits::TTracebackType,
+                                  Parallel>;
+
+    // Setup the score and trace matrix.
+    TDPScoreMatrix dpScoreMatrix;
+    TDPTraceMatrix dpTraceMatrix;
+
+    setLength(dpScoreMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1);
+    setLength(dpScoreMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1);
+
+    setLength(dpTraceMatrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1);
+    setLength(dpTraceMatrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1);
+
+    // Resue the buffer from the cache.
+    setHost(dpScoreMatrix, getDpScoreMatrix(dpContext));
+    setHost(dpTraceMatrix, getDpTraceMatrix(dpContext));
+
+    resize(dpScoreMatrix);
+    // We do not need to allocate the memory for the trace matrix if the traceback is disabled.
+    if /*constexpr*/(IsTracebackEnabled_<typename TDPTraits::TTracebackType>::VALUE)
+    {
+        static_assert(std::is_same<typename TDPTraits::TTracebackType, TracebackOff>::value, "Traceback not implemented!");
+        resize(dpTraceMatrix);
+    }
+
+    // Initialize the navigators.
+    TDPScoreMatrixNavigator dpScoreMatrixNavigator{dpScoreMatrix, DPBandConfig<BandOff>{}};
+    TDPTraceMatrixNavigator dpTraceMatrixNavigator{dpTraceMatrix, DPBandConfig<BandOff>{}};
+
+    // Execute the alignment.
+    _computeAlignmentImpl(scout, dpScoreMatrixNavigator, dpTraceMatrixNavigator, seqH, seqV,
+                          scoringScheme, DPBandConfig<BandOff>{}, TDPProfile(), NavigateColumnWise{});
+}
+
+#ifdef SEQAN_SIMD_ENABLED
+// Some utility functions.
+template <typename TTasks,
+          typename TScoreValueScalar,
+          typename TScoreValueSimd>
+inline auto
+doComputeOffset(TTasks const &tasks,
+                TScoreValueScalar const & /*scalarScore*/,
+                TScoreValueSimd const & /*simdScore*/)
+{
+    String<TScoreValueScalar> offset;
+    resize(offset, length(tasks), std::numeric_limits<TScoreValueScalar>::min(), Exact());
+
+    size_t pos = 0;
+
+    for (auto task : tasks)
+    {
+            offset[pos] = front(context(*task).tileBuffer.horizontalBuffer[column(*task)]).i1._score;
+        ++pos;
+    }
+
+    return offset;
+}
+
+template <typename TTasks,
+          typename TScoreValue>
+inline auto
+doComputeOffset(TTasks const &tasks,
+                TScoreValue const & /*scalarScore*/,
+                TScoreValue const & /*simdScore*/)
+{
+    String<TScoreValue> offset;
+    resize(offset, length(tasks), 0, Exact());
+    return offset;
+}
+
+template <typename TTasks,
+          typename TTaskTraits>
+inline auto
+computeOffset(TTasks const &tasks, TTaskTraits const & /*traits*/)
+{
+    using TDPSettings       = typename TTaskTraits::TDPSettings;
+    using TScoreValueScalar = typename Value<typename TDPSettings::TScoringScheme>::Type;
+    using TScoreValueSimd   = typename Value<typename TDPSettings::TSimdScoringScheme>::Type;
+    using TDPSimdValue      = typename Value<TScoreValueSimd>::Type;
+
+    return doComputeOffset(tasks, TScoreValueScalar{}, TDPSimdValue{});
+}
+
+template <typename TDPCell, typename TTrace,
+          typename TTasks,
+          typename TPos,
+          typename TFunc,
+          typename TOffset>
+inline void
+loadIntoSimd(Pair<TDPCell, TTrace> & target,
+             TTasks const & tasks,
+             TPos const pos,
+             TFunc && getBuffer,
+             TOffset const & offset,
+             LinearGaps const & /*unsused*/)
+{
+    using TSimdVec = typename Value<TDPCell>::Type;
+    using TVecVal = typename Value<TSimdVec>::Type;
+
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> scoreVec;
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> traceVec;
+
+    auto zipCont = makeZipView(tasks, scoreVec, traceVec, offset);
+
+    std::for_each(begin(zipCont), end(zipCont),
+                  [&, getBuffer = std::move(getBuffer)](auto tuple)
+                  {
+                      auto & buffer = *getBuffer(*std::get<0>(tuple));
+                      auto val = (length(buffer) > pos) ? buffer[pos] : typename std::decay<decltype(buffer[0])>::type{};
+
+                      // We might access values out of bounds here.
+                      std::get<1>(tuple) = static_cast<TVecVal>(val.i1._score - std::get<3>(tuple));
+                      std::get<2>(tuple) = val.i2;
+                  });
+
+    target.i1._score = load<TSimdVec>(&scoreVec[0]);
+    target.i2 = load<TSimdVec>(&traceVec[0]);
+}
+
+template <typename TDPCell, typename TTrace,
+          typename TTasks,
+          typename TPos,
+          typename TFunc,
+          typename TOffset>
+inline void
+loadIntoSimd(Pair<TDPCell, TTrace> & target,
+             TTasks const & tasks,
+             TPos const pos,
+             TFunc && getBuffer,
+             TOffset const & offset,
+             AffineGaps const & /*unsused*/)
+{
+    using TSimdVec = typename Value<TDPCell>::Type;
+    using TVecVal = typename Value<TSimdVec>::Type;
+
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> scoreVec;
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> scoreHorVec;
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> scoreVerVec;
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> traceVec;
+
+    auto zipCont = makeZipView(tasks, scoreVec, scoreHorVec, scoreVerVec, traceVec, offset);
+
+    std::for_each(begin(zipCont), end(zipCont),
+                  [&, getBuffer = std::move(getBuffer)](auto tuple)
+                  {
+                      auto & buffer = *getBuffer(*std::get<0>(tuple));
+                      auto val = (length(buffer) > pos) ? buffer[pos] : typename std::decay<decltype(buffer[0])>::type{};
+                      using TDPCellVar = decltype(val.i1);
+                      using TDPCell16 = DPCell_<TVecVal, AffineGaps>;
+
+                      // We might access values out of bounds here.
+                      std::get<1>(tuple) = static_cast<TVecVal>(val.i1._score - std::get<5>(tuple));
+
+                      std::get<2>(tuple) =
+                        (val.i1._horizontalScore <= DPCellDefaultInfinity<TDPCellVar>::VALUE) ?
+                            DPCellDefaultInfinity<TDPCell16>::VALUE :
+                            static_cast<TVecVal>(val.i1._horizontalScore - std::get<5>(tuple));
+                      std::get<3>(tuple) =
+                        (val.i1._verticalScore <= DPCellDefaultInfinity<TDPCellVar>::VALUE) ?
+                        DPCellDefaultInfinity<TDPCell16>::VALUE :
+                        static_cast<TVecVal>(val.i1._verticalScore - std::get<5>(tuple));
+                      std::get<4>(tuple) = val.i2;
+                  });
+
+    target.i1._score = load<TSimdVec>(&scoreVec[0]);
+    target.i1._horizontalScore = load<TSimdVec>(&scoreHorVec[0]);
+    target.i1._verticalScore = load<TSimdVec>(&scoreVerVec[0]);
+    target.i2 = load<TSimdVec>(&traceVec[0]);
+}
+
+template <typename TTasks,
+          typename TDPCell, typename TTrace,
+          typename TPos,
+          typename TFunc,
+          typename TOffset>
+inline void
+storeIntoBuffer(TTasks & tasks,
+                Pair<TDPCell, TTrace> const & source,
+                TPos const pos,
+                TFunc && getBuffer,
+                TOffset const & offset,
+                LinearGaps const & /*unsused*/)
+{
+    using TSimdVec = typename Value<TDPCell>::Type;
+    using TVecVal = typename Value<TSimdVec>::Type;
+
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> scoreVec;
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> traceVec;
+
+    storeu(&scoreVec[0], source.i1._score);
+    storeu(&traceVec[0], source.i2);
+
+    auto zipCont = makeZipView(tasks, scoreVec, traceVec, offset);
+
+    std::for_each(begin(zipCont), end(zipCont),
+                  [&, getBuffer = std::move(getBuffer)] (auto tuple)
+                  {
+                      auto & buffer = *getBuffer(*std::get<0>(tuple));
+                      if (length(buffer) > pos)
+                      {
+                          auto & pair = buffer[pos];
+                          pair.i1._score = std::get<1>(tuple) + std::get<3>(tuple);
+                          pair.i2 = std::get<2>(tuple);
+                      }
+                  });
+}
+
+template <typename TTasks,
+          typename TDPCell, typename TTrace,
+          typename TPos,
+          typename TFunc,
+          typename TOffset>
+inline void
+storeIntoBuffer(TTasks & tasks,
+                Pair<TDPCell, TTrace> const & source,
+                TPos const pos,
+                TFunc && getBuffer,
+                TOffset const & offset,
+                AffineGaps const & /*unsused*/)
+{
+    using TSimdVec = typename Value<TDPCell>::Type;
+    using TVecVal = typename Value<TSimdVec>::Type;
+
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> scoreVec;
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> scoreHorVec;
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> scoreVerVec;
+    alignas(sizeof(TSimdVec)) std::array<TVecVal, LENGTH<TSimdVec>::VALUE> traceVec;
+
+    storeu(&scoreVec[0], source.i1._score);
+    storeu(&scoreHorVec[0], source.i1._horizontalScore);
+    storeu(&scoreVerVec[0], source.i1._verticalScore);
+    storeu(&traceVec[0], source.i2);
+
+    auto zipCont = makeZipView(tasks, scoreVec, scoreHorVec, scoreVerVec, traceVec, offset);
+
+    std::for_each(begin(zipCont), end(zipCont),
+                  [&, getBuffer = std::move(getBuffer)](auto tuple)
+                  {
+                      auto & buffer = *getBuffer(*std::get<0>(tuple));
+                      if (length(buffer) > pos)
+                      {
+                          auto & pair = buffer[pos];
+                          pair.i1._score = std::get<1>(tuple) + std::get<5>(tuple);
+                          pair.i1._horizontalScore = std::get<2>(tuple) + std::get<5>(tuple);
+                          pair.i1._verticalScore = std::get<3>(tuple) + std::get<5>(tuple);
+                          pair.i2 = std::get<4>(tuple);
+                      }
+                  });
+}
+
+template <typename TTasks,
+          typename TFunc,
+          typename TOffset,
+          typename TExecTraits>
+inline auto
+gatherSimdBuffer(TTasks const & tasks,
+                 TFunc && getBuffer,
+                 TOffset const & offset,
+                 TExecTraits const & /*traits*/)
+{
+    // Check for valid simd length.
+    SEQAN_ASSERT_EQ(LENGTH<typename TExecTraits::TScoreValue>::VALUE, length(tasks));
+
+    String<typename TExecTraits::TBufferValue, Alloc<OverAligned> > simdSet;
+
+    auto maxLength = length(*getBuffer(*tasks[0]));
+    std::for_each(begin(tasks, Standard()) + 1, end(tasks, Standard()),
+                  [&](auto & task)
+                  {
+                      auto len = length(*getBuffer(*task));
+                      maxLength = (len > maxLength) ? len : maxLength;
+                  });
+
+    resize(simdSet, maxLength, Exact());
+    for (unsigned i = 0; i < length(simdSet); ++i)
+    {
+        loadIntoSimd(simdSet[i], tasks, i, std::forward<TFunc>(getBuffer), offset, typename TExecTraits::TGapType());
+    }
+    return simdSet;
+}
+
+template <typename TTasks,
+          typename TBufferValue, typename TSpec,
+          typename TFunc,
+          typename TOffset,
+          typename TExecTraits>
+inline void
+scatterSimdBuffer(TTasks & tasks,
+                  String<TBufferValue, TSpec> const & simdSet,
+                  TFunc && getBuffer,
+                  TOffset const & offset,
+                  TExecTraits const & /*traits*/)
+{
+    for (unsigned i = 0; i < length(simdSet); ++i)
+    {
+        storeIntoBuffer(tasks, simdSet[i], i, std::forward<TFunc>(getBuffer), offset, typename TExecTraits::TGapType());
+    }
+}
+
+// Compute tasks as simd alignment.
+template <typename TDPCell, typename TTraceValue, typename TScoreMat, typename TTraceMat,
+          typename TTasks,
+          typename TSimdBufferH,
+          typename TSimdBufferV,
+          typename TDPLocal,
+          typename TOffset,
+          typename TExecTraits>
+inline void
+computeSimdBatch(DPContext<TDPCell, TTraceValue, TScoreMat, TTraceMat> & cache,
+                 TSimdBufferH                                          & bufferH,
+                 TSimdBufferV                                          & bufferV,
+                 TTasks                                                & tasks,
+                 TDPLocal                                              & dpLocal,
+                 TOffset                                               & offset,
+                 TExecTraits                                     const & /*traits*/)
+{
+    // Now what?
+    using TSeqH    = typename TExecTraits::TSeqH;
+    using TSeqV    = typename TExecTraits::TSeqV;
+    using TSimdVec = typename TExecTraits::TScoreValue;
+
+    // Prepare sequence set.
+    StringSet<TSeqH, Dependent<> > depSetH;
+    StringSet<TSeqV, Dependent<> > depSetV;
+    bool allSameLength = true;
+    auto ptrTask = tasks[0];
+    auto lenH = length(context(*ptrTask).seqHBlocks[column(*ptrTask)]);
+    auto lenV = length(context(*ptrTask).seqVBlocks[row(*ptrTask)]);
+
+    for (auto ptrTask : tasks)
+    {
+        appendValue(depSetH, context(*ptrTask).seqHBlocks[column(*ptrTask)]);
+        appendValue(depSetV, context(*ptrTask).seqVBlocks[row(*ptrTask)]);
+        if (lenH != length(context(*ptrTask).seqHBlocks[column(*ptrTask)]) ||
+            lenV != length(context(*ptrTask).seqVBlocks[row(*ptrTask)]))
+        {
+            allSameLength = false;
+        }
+    }
+
+    // Dummy trace set.
+    StringSet<String<Nothing> > trace;  // We need to instantiate it, but it will not be used.
+
+    // We can compute with one simd score, but might collect them here.
+    auto const & scoringScheme = context(*tasks[0]).dpSettings.simdScoringScheme;
+
+    // Preapare and run alingment.
+    String<TSimdVec, Alloc<OverAligned> > stringSimdH;
+    String<TSimdVec, Alloc<OverAligned> > stringSimdV;
+
+    if (allSameLength)
+    {
+        using TScoutState = DPScoutState_<DPTiled<TSimdBufferH, Default, SimdAlignEqualLength>>;
+        TScoutState scoutState(bufferH, bufferV);
+        _prepareSimdAlignment(stringSimdH, stringSimdV, depSetH, depSetV, scoutState);
+
+        using TScoutSpec = typename ScoutSpecForAlignmentAlgorithm_<typename TExecTraits::TAlgorithmType, TScoutState>::Type;
+        using TDPScout = DPScout_<TDPCell, TScoutSpec>;
+
+        TDPScout dpScout(scoutState);
+        // We rather want to set
+        computeTile(cache, dpScout, stringSimdH, stringSimdV, scoringScheme, context(*tasks[0]).dpSettings);
+
+        // Now we need to run the scout check for all tasks.
+
+        // We want to get the state here from the scout.
+        for (size_t pos = 0; pos < length(tasks); ++pos)
+        {
+            auto & task = *tasks[pos];
+            if (AlgorithmProperty<typename TExecTraits::TAlgorithmType>::isTrackingEnabled(task))
+            {
+                // TODO(rrahn): Implement the interface.
+                // TODO(rrahn): Make it a member function of a policy so that we don't have to implement the specifics here
+                _setSimdLane(dpScout, pos);
+                auto & taskContext = context(task);
+                updateMax(intermediate(dpLocal, taskContext.alignmentId),
+                          {maxScoreAt(dpScout) + offset[pos], 0u},
+                          column(task),
+                          row(task));
+            }
+        }
+    }
+    else
+    {
+        using TDPSettings = std::decay_t<decltype(context(*tasks[0]).dpSettings)>;
+        using TDPTraits = typename TDPSettings::TTraits;
+
+        using TDPProfile = DPProfile_<typename TDPTraits::TAlgorithmType,
+                                      typename TDPTraits::TGapType,
+                                      typename TDPTraits::TTracebackType,
+                                      Parallel>;
+
+        using TSimdScoutTrait = SimdAlignVariableLengthTraits<TSimdVec,
+                                                              decltype(depSetH),
+                                                              decltype(depSetV),
+                                                              TDPProfile>;
+        using TScoutState = DPScoutState_<DPTiled<TSimdBufferH, Default, SimdAlignVariableLength<TSimdScoutTrait>>>;
+
+        String<size_t> lengthsH;
+        String<size_t> lengthsV;
+
+        TScoutState scoutState(bufferH, bufferV);
+        _prepareSimdAlignment(stringSimdH, stringSimdV, depSetH, depSetV, lengthsH, lengthsV, scoutState);
+
+        using TScoutSpec = typename ScoutSpecForAlignmentAlgorithm_<typename TExecTraits::TAlgorithmType, TScoutState>::Type;
+        using TDPScout = DPScout_<TDPCell, TScoutSpec>;
+
+        TDPScout dpScout(scoutState);
+        computeTile(cache, dpScout, stringSimdH, stringSimdV, scoringScheme, context(*tasks[0]).dpSettings);
+        // We want to get the state here from the scout.
+        for (size_t pos = 0; pos < length(tasks); ++pos)
+        {
+            auto & task = *tasks[pos];
+            if (AlgorithmProperty<typename TExecTraits::TAlgorithmType>::isTrackingEnabled(task))
+            {
+                // TODO(rrahn): Implement the interface.
+                // TODO(rrahn): Make it a member function of a policy so that we don't have to implement the specifics here
+                _setSimdLane(dpScout, pos);
+                auto & taskContext = context(task);
+                updateMax(intermediate(dpLocal, taskContext.alignmentId),
+                          {maxScoreAt(dpScout) + offset[pos], 0u},
+                          column(task),
+                          row(task));
+            }
+        }
+    }
+}
+#endif // SEQAN_SIMD_ENABLED
+}  // namespace impl
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_WAVEFRONT_TASK_UTIL_H_
diff --git a/include/seqan/align_split/align_split_interface.h b/include/seqan/align_split/align_split_interface.h
index f1db184..69d3a9e 100644
--- a/include/seqan/align_split/align_split_interface.h
+++ b/include/seqan/align_split/align_split_interface.h
@@ -98,12 +98,12 @@ template <typename TSpec>
 struct IsSplitAlignment_<SplitAlignment_<TSpec> const>:
     True {};
 
-template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag>
-struct IsSplitAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag> >:
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct IsSplitAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> >:
     IsSplitAlignment_<TAlgoSpec> {};
 
-template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag>
-struct IsSplitAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag> const>:
+template <typename TAlgoSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy>
+struct IsSplitAlignment_<DPProfile_<TAlgoSpec, TGapCosts, TTraceFlag, TExecPolicy> const>:
     IsSplitAlignment_<TAlgoSpec> {};
 
 // ----------------------------------------------------------------------------
@@ -176,10 +176,12 @@ struct LastRowEnabled_<SplitAlignment_<TSpec>, LastCell, TColumnDescriptor>
 // Metafunction DPMetaColumn_
 // ----------------------------------------------------------------------------
 
-template <typename TSpec, typename TGapCosts, typename TTraceFlag, typename TColumnType>
-struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag>, MetaColumnDescriptor<TColumnType, FullColumn> >
+template <typename TSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy,
+          typename TColumnType>
+struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag, TExecPolicy>,
+                     MetaColumnDescriptor<TColumnType, FullColumn> >
 {
-    typedef DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag> TDPProfile;
+    typedef DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag, TExecPolicy> TDPProfile;
     typedef typename IsLocalAlignment_<TDPProfile>::Type TIsLocal;
 
     // If InitialColumn -> Zero, Vertical | Zero, Vertical | Zero  // Within the algorithm we need to define the first row as only one cell if it is no initial column
@@ -201,8 +203,10 @@ struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag>,
 };
 
 
-template <typename TSpec, typename TGapCosts, typename TTraceFlag, typename TColumnType>
-struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag>, MetaColumnDescriptor<TColumnType, PartialColumnTop> >
+template <typename TSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy,
+          typename TColumnType>
+struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag, TExecPolicy>,
+                     MetaColumnDescriptor<TColumnType, PartialColumnTop> >
 {
     typedef DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag> TDPProfile;
     typedef typename IsLocalAlignment_<TDPProfile>::Type TIsLocal;
@@ -227,10 +231,12 @@ struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag>,
     typedef DPMetaCell_<TRecursionTypeLastCell_, True> TLastCell_;
 };
 
-template <typename TSpec, typename TGapCosts, typename TTraceFlag, typename TColumnType>
-struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag>, MetaColumnDescriptor<TColumnType, PartialColumnMiddle> >
+template <typename TSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy,
+          typename TColumnType>
+struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag, TExecPolicy>,
+                     MetaColumnDescriptor<TColumnType, PartialColumnMiddle> >
 {
-    typedef DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag> TDPProfile;
+    typedef DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag, TExecPolicy> TDPProfile;
     typedef typename IsLocalAlignment_<TDPProfile>::Type TIsLocal;
 
     // If InitialColumn -> Zero, Vertical | Zero, Vertical | Zero  // Within the algorithm we need to define the first row as only one cell if it is no initial column
@@ -250,10 +256,12 @@ struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag>,
     typedef DPMetaCell_<TRecursionTypeLastCell_, True> TLastCell_;
 };
 
-template <typename TSpec, typename TGapCosts, typename TTraceFlag, typename TColumnType>
-struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag>, MetaColumnDescriptor<TColumnType, PartialColumnBottom> >
+template <typename TSpec, typename TGapCosts, typename TTraceFlag, typename TExecPolicy,
+          typename TColumnType>
+struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag, TExecPolicy>,
+                     MetaColumnDescriptor<TColumnType, PartialColumnBottom> >
 {
-    typedef DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag> TDPProfile;
+    typedef DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag, TExecPolicy> TDPProfile;
     typedef typename IsLocalAlignment_<TDPProfile>::Type TIsLocal;
 
     // If InitialColumn -> Zero, Vertical | Zero, Vertical | Zero  // Within the algorithm we need to define the first row as only one cell if it is no initial column
@@ -280,7 +288,7 @@ struct DPMetaColumn_<DPProfile_<SplitAlignment_<TSpec>, TGapCosts, TTraceFlag>,
 template <typename TFreeEndGaps, typename TGapCosts, typename TTraceSwitch>
 struct SetupAlignmentProfile_<SplitAlignmentAlgo, TFreeEndGaps, TGapCosts, TTraceSwitch>
 {
-    typedef DPProfile_<SplitAlignment_<TFreeEndGaps>, TGapCosts, TTraceSwitch> Type;
+    typedef DPProfile_<SplitAlignment_<TFreeEndGaps>, TGapCosts, TTraceSwitch, Serial> Type;
 };
 
 // ============================================================================
@@ -330,7 +338,7 @@ void _computeSplitTrace(TTarget & target,
 {
     typedef typename SetupAlignmentProfile_<TDPType, TFreeEndGaps, LinearGaps, TTraceConfig>::Type TDPProfile;
 
-    typedef typename GetDPTraceMatrix<TDPContext const>::Type TDPTraceMatrixHost;
+    using TDPTraceMatrixHost = std::remove_reference_t<decltype(getDpTraceMatrix(dpContext))>;
     typedef typename Value<TDPTraceMatrixHost>::Type TTraceValue;
 
     typedef DPMatrix_<TTraceValue, FullDPMatrix> TDPTraceMatrix;
@@ -339,7 +347,7 @@ void _computeSplitTrace(TTarget & target,
     TDPTraceMatrix matrix;
     setLength(matrix, +DPMatrixDimension_::HORIZONTAL, length(seqH) + 1 - std::max(0, lowerDiagonal(config._band)));
 
-    if (IsSameType<TBandSwitch, BandOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TBandSwitch, BandOff>::VALUE)
     {
         setLength(matrix, +DPMatrixDimension_::VERTICAL, length(seqV) + 1);
     }
@@ -353,8 +361,7 @@ void _computeSplitTrace(TTarget & target,
     setHost(matrix, getDpTraceMatrix(dpContext));
     resize(matrix);
     SEQAN_ASSERT_EQ(length(getDpTraceMatrix(dpContext)), length(matrix));
-    TDPTraceMatrixNavigator navi;
-    _init(navi, matrix, config._band);
+    TDPTraceMatrixNavigator navi{matrix, config._band};
     _computeTraceback(target, navi, matPos, seqH, seqV, config._band, TDPProfile());
 }
 
@@ -387,7 +394,7 @@ auto _splitAlignmentImpl(Gaps<TContigSeqL> & gapsContigL,
 
     // Compute trace and split score sequence for the left alignment.
     // We actually need to first compute the scores, than trace from the choosen split position.
-    DPContext<TScoreValue, TGapModel> dpContextL;
+    DPContext<DPCell_<TScoreValue, TGapModel>, typename TraceBitMap_<TScoreValue>::Type> dpContextL;
     DPScoutState_<SplitAlignmentScout> scoutStateL;
     resize(scoutStateL.splitScore, length(source(gapsContigL)) + 1, std::numeric_limits<TScoreValue>::min() / 2);
     resize(scoutStateL.splitPos, length(scoutStateL.splitScore));
@@ -400,7 +407,7 @@ auto _splitAlignmentImpl(Gaps<TContigSeqL> & gapsContigL,
     ModifiedString<TReadSeqR, ModReverse> revReadR(source(gapsReadR));
 
     // Compute trace and split score sequence for the right alignment.
-    DPContext<TScoreValue, TGapModel> dpContextR;
+    DPContext<DPCell_<TScoreValue, TGapModel>, typename TraceBitMap_<TScoreValue>::Type> dpContextR;
     DPScoutState_<SplitAlignmentScout> scoutStateR;
     resize(scoutStateR.splitScore, length(source(gapsContigR)) + 1, std::numeric_limits<TScoreValue>::min() / 2);
     resize(scoutStateR.splitPos, length(scoutStateR.splitScore));
diff --git a/include/seqan/arg_parse/arg_parse_argument.h b/include/seqan/arg_parse/arg_parse_argument.h
index 95ebf88..03f473f 100644
--- a/include/seqan/arg_parse/arg_parse_argument.h
+++ b/include/seqan/arg_parse/arg_parse_argument.h
@@ -438,6 +438,28 @@ inline bool isOutputFileArgument(ArgParseArgument const & me)
 }
 
 // ----------------------------------------------------------------------------
+// Function isDirectoryArgument()
+// ----------------------------------------------------------------------------
+
+/*!
+ * @fn ArgParseArgument#isDirectoryArgument
+ * @headerfile <seqan/arg_parse.h>
+ * @brief Returns whether the argument is a directorz argument.
+ *
+ * @signature bool isDirectoryArgument(arg);
+ *
+ * @param[in] arg The ArgParseArgument to query.
+ *
+ * @return bool <tt>true</tt> if it is a directory argument, <tt>false</tt> otherwise.
+ */
+
+inline bool isDirectoryArgument(ArgParseArgument const & me)
+{
+    return me._argumentType == ArgParseArgument::INPUT_DIRECTORY ||
+           me._argumentType == ArgParseArgument::OUTPUT_DIRECTORY;
+}
+
+// ----------------------------------------------------------------------------
 // Function isOutputPrefixArgument()
 // ----------------------------------------------------------------------------
 
@@ -923,7 +945,15 @@ inline void _checkValue(ArgParseArgument const & me)
 {
     unsigned i = 0;
     for (std::vector<std::string>::const_iterator it = me.value.begin(); it != me.value.end(); ++it, ++i)
-        _checkValue(me, *it, i);
+    {
+        auto val = *it;
+
+        if (isDirectoryArgument(me)) // strip trailing slash for directories
+            if (val[length(val) - 1] == '/')
+                val.resize(length(val) - 1);
+
+        _checkValue(me, val, i);
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -1138,6 +1168,10 @@ inline std::string getFileExtension(ArgParseArgument const & me, unsigned pos =
     if (value.empty())
         return "";
 
+    if (isDirectoryArgument(me)) // strip trailing slash for directories
+        if (value[length(value) - 1] == '/')
+            value.resize(length(value) - 1);
+
     // If there is a list of valid values then we look for each of these in the path.
     if (!me.validValues.empty())
     {
diff --git a/include/seqan/arg_parse/tool_doc.h b/include/seqan/arg_parse/tool_doc.h
index a19a983..970c0e3 100644
--- a/include/seqan/arg_parse/tool_doc.h
+++ b/include/seqan/arg_parse/tool_doc.h
@@ -444,6 +444,13 @@ public:
         std::fill_n(out, _layout.leftPadding, ' ');
         stream << _toText(listItem._term);
         unsigned pos = _layout.leftPadding + length(listItem._term);
+
+        if (empty(listItem._description))
+        {
+            stream << '\n';
+            return;
+        }
+
         if (pos + _layout.centerPadding > _layout.rightColumnTab)
         {
             stream << '\n';
diff --git a/include/seqan/bam_io/bam_alignment_record_util.h b/include/seqan/bam_io/bam_alignment_record_util.h
index 1a7a02f..15d1ac1 100644
--- a/include/seqan/bam_io/bam_alignment_record_util.h
+++ b/include/seqan/bam_io/bam_alignment_record_util.h
@@ -237,7 +237,7 @@ bamRecordToAlignment(Align<TSource, TSpec> & result, TReference & reference, Bam
     // TODO(holtgrew): Clipping better than copying infix? But is it generic?
     resize(rows(result), 2);
 
-    unsigned len = record.beginPos + getAlignmentLengthInRef(record) - countPaddings(record.cigar);
+    unsigned len = getAlignmentLengthInRef(record) - countPaddings(record.cigar);
 
     setSource(row(result, 0), reference);
     setClippedEndPosition(row(result, 0), record.beginPos + len);
diff --git a/include/seqan/bam_io/bam_index_bai.h b/include/seqan/bam_io/bam_index_bai.h
index bbd07a8..222a757 100644
--- a/include/seqan/bam_io/bam_index_bai.h
+++ b/include/seqan/bam_io/bam_index_bai.h
@@ -162,24 +162,29 @@ public:
  * @fn BamFileIn#jumpToRegion
  * @brief Seek in BamFileIn using an index.
  *
- * You provide a region <tt>[pos, posEnd)</tt> on the reference <tt>refID</tt> that you want to jump to and the function
- * jumps to the first alignment in this region, if any.
+ * You provide a region <tt>[regionStart, regionEnd]</tt> on the reference <tt>refID</tt>
+ * that you want to jump to and the function jumps to the first alignment (bam record)
+ * whose start position lies inside this region, if any.
+ * Note: The current inmplementation only consideres the read start positions.
+ *       Therefore, we do guarantee that reads overlapping the region are included.
+ *       To account for this limitation you may want to choose the start of your
+ *       your region with an appropiate offset (e.g. start - length_of_read).
  *
- * @signature bool jumpToRegion(bamFileIn, hasAlignments, refID, pos, posEnd, index);
+ * @signature bool jumpToRegion(bamFileIn, hasAlignments, refID, regionStart, regionEnd, index);
  *
  * @param[in,out] bamFileIn     The @link BamFileIn @endlink to jump with.
- * @param[out]    hasAlignments A <tt>bool</tt> that is set true if the region <tt>[pos, posEnd)</tt> has any
- *                              alignments.
+ * @param[out]    hasAlignments A <tt>bool</tt> that is set true if the region <tt>[regionStart, regionEnd]</tt> has any
+ *                              at least one overlapping alignment (bam record).
  * @param[in]     refID         The reference id to jump to (<tt>int32_t</tt>).
- * @param[in]     pos           The begin of the region to jump to (<tt>int32_t</tt>).
- * @param[in]     posEnd        The end of the region to jump to (<tt>int32_t</tt>).
+ * @param[in]     regionStart   The begin of the region to jump to (<tt>int32_t</tt>).
+ * @param[in]     regionEnd     The end of the region to jump to (<tt>int32_t</tt>).
  * @param[in]     index         The @link BamIndex @endlink to use for the jumping.
  *
  * @return bool true if seeking was successful, false if not.
  *
  * @section Remarks
  *
- * This function fails if <tt>refID</tt>/<tt>pos</tt> are invalid.
+ * This function fails if <tt>refID</tt>/<tt>regionStart</tt> are invalid.
  */
 
 static inline void
@@ -202,8 +207,8 @@ inline bool
 jumpToRegion(FormattedFile<Bam, Input, TSpec> & bamFile,
              bool & hasAlignments,
              int32_t refId,
-             int32_t pos,
-             int32_t posEnd,
+             int32_t regionStart,
+             int32_t regionEnd,
              BamIndex<Bai> const & index)
 {
     if (!isEqual(format(bamFile), Bam()))
@@ -220,12 +225,12 @@ jumpToRegion(FormattedFile<Bam, Input, TSpec> & bamFile,
     // ------------------------------------------------------------------------
     uint64_t offset = std::numeric_limits<uint64_t>::max();
 
-    // Retrieve the candidate bin identifiers for [pos, posEnd).
+    // Retrieve the candidate bin identifiers for [regionStart, regionEnd).
     String<uint16_t> candidateBins;
-    _baiReg2bins(candidateBins, pos, posEnd);
+    _baiReg2bins(candidateBins, regionStart, regionEnd);
 
     // Retrieve the smallest required offset from the linear index.
-    unsigned windowIdx = pos >> 14;  // Linear index consists of 16kb windows.
+    unsigned windowIdx = regionStart >> 14;  // Linear index consists of 16kb windows.
     uint64_t linearMinOffset = 0;
     if (windowIdx >= length(index._linearIndices[refId]))
     {
@@ -298,24 +303,43 @@ jumpToRegion(FormattedFile<Bam, Input, TSpec> & bamFile,
         readRecord(record, bamFile);
 
         // std::cerr << "record.beginPos == " << record.beginPos << "\n";
-         int32_t endPos = record.beginPos + getAlignmentLengthInRef(record);
         if (record.rID != refId)
             continue;  // Wrong contig.
-        if (!hasAlignments && record.beginPos <= posEnd && pos <= endPos)
+
+        if (record.beginPos <= regionStart)
         {
-            // Found a valid alignment.
-            hasAlignments = true;
             offset = *candIt;
         }
 
-        if (record.beginPos >= posEnd)
+        if (record.beginPos >= regionEnd)
             break;  // Cannot find overlapping any more.
     }
 
-    if (offset != std::numeric_limits<uint64_t>::max())
-        setPosition(bamFile, offset);
+    if (offset == std::numeric_limits<uint64_t>::max())
+        return true; // Finding no overlapping alignment is not an error, hasAlignments is false.
+
+    // Now only the right most offset was found but it is not ensured that the
+    // alignment at the start of the offset lies inside the region.
+    // Therefore we must advance further or until the region ends.
+    setPosition(bamFile, offset);
+
+    while (!atEnd(bamFile))
+    {
+        auto seek_pos = position(bamFile); // store current pos to reset bamFile if necessary
+
+        readRecord(record, bamFile);
+
+        if (record.beginPos >= regionEnd)
+            break;
+
+        if (record.beginPos >= regionStart)
+        {
+            hasAlignments = true;
+            setPosition(bamFile, seek_pos);
+            break;
+        }
+    }
 
-    // Finding no overlapping alignment is not an error, hasAlignments is false.
     return true;
 }
 
diff --git a/include/seqan/bam_io/read_bam.h b/include/seqan/bam_io/read_bam.h
index 8d5143f..12c81c2 100644
--- a/include/seqan/bam_io/read_bam.h
+++ b/include/seqan/bam_io/read_bam.h
@@ -267,7 +267,7 @@ readRecord(BamAlignmentRecord & record,
     TQualIter qitEnd = end(record.qual, Standard());
     for (TQualIter qit = begin(record.qual, Standard()); qit != qitEnd;)
         *qit++ = '!' + *it++;
-    if (!empty(record.qual) && record.qual[0] == '\xff')
+    if (!empty(record.qual) && (record.qual[0] - '!') == '\xff')
         clear(record.qual);
 
     // tags
diff --git a/include/seqan/basic/basic_exception.h b/include/seqan/basic/basic_exception.h
index 8a5a95a..b9b3d8d 100644
--- a/include/seqan/basic/basic_exception.h
+++ b/include/seqan/basic/basic_exception.h
@@ -369,7 +369,7 @@ inline static void globalExceptionHandler()
 }
 
 // Install global exception handler.
-static const std::terminate_handler SEQAN_UNUSED _globalExceptionHandler = std::set_terminate(globalExceptionHandler);
+static const std::terminate_handler _globalExceptionHandler SEQAN_UNUSED = std::set_terminate(globalExceptionHandler);
 
 #endif  // #if defined(SEQAN_EXCEPTIONS) && defined(SEQAN_GLOBAL_EXCEPTION_HANDLER)
 
diff --git a/include/seqan/basic/fundamental_metafunctions.h b/include/seqan/basic/fundamental_metafunctions.h
index 7f3a702..eedaf63 100644
--- a/include/seqan/basic/fundamental_metafunctions.h
+++ b/include/seqan/basic/fundamental_metafunctions.h
@@ -202,12 +202,24 @@ struct Spec
     typedef void Type;
 };
 
-// Case for one template argument.
+// Case for variable number of template arguments.
+// Note, that a spec by default should be the last template argument in SeqAn.
+// This helper recursively reduces the template argument list to the last template argument.
+template <size_t REMAINING, typename T1, typename ...TRemainingTypes>
+struct GetSpecHelper_ : GetSpecHelper_<sizeof...(TRemainingTypes), TRemainingTypes...>
+{};
+
+// Recursion anchor.
+template <typename T1>
+struct GetSpecHelper_<1, T1>
+{
+    using Type = T1;
+};
 
-template <template <typename> class T, typename TSpec>
-struct Spec<T<TSpec> >
+template <template <typename ...> class T, typename ...TArgs>
+struct Spec<T<TArgs...> >
 {
-    typedef TSpec Type;
+    using Type = typename GetSpecHelper_<sizeof...(TArgs), TArgs...>::Type;
 };
 
 template <typename T>
diff --git a/include/seqan/basic/fundamental_tags.h b/include/seqan/basic/fundamental_tags.h
index ce6dd76..3de0db6 100644
--- a/include/seqan/basic/fundamental_tags.h
+++ b/include/seqan/basic/fundamental_tags.h
@@ -549,7 +549,7 @@ inline bool tagSelectIntersect(TagSelector<TOutTagList> & outTagList, Tag<TagSpe
 {
     typedef typename TOutTagList::Type TFormat;
 
-    if (IsSameType<Tag<TagSpec>, TFormat>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<Tag<TagSpec>, TFormat>::VALUE)
     {
         outTagList.tagId = LENGTH<TOutTagList>::VALUE - 1;
         return true;
diff --git a/include/seqan/basic/iterator_range.h b/include/seqan/basic/iterator_range.h
index 74e7c23..eb2c80b 100644
--- a/include/seqan/basic/iterator_range.h
+++ b/include/seqan/basic/iterator_range.h
@@ -80,19 +80,19 @@ public:
     // Range Constructors
     // ------------------------------------------------------------------------
 
-   
+
     Range():
         begin(),
         end()
     {}
 
-   
+
     Range(Range const & range) :
         begin(range.begin),
         end(range.end)
     {}
 
-   
+
     Range(TIterator const & begin, TIterator const & end):
         begin(begin),
         end(end)
@@ -102,10 +102,18 @@ public:
     // Operator =
     // ------------------------------------------------------------------------
 
+    Range &
+    operator=(Range const & other)
+    {
+        begin = other.begin;
+        end = other.end;
+        return *this;
+    }
+
     template <typename TOtherContainer>
-   
+
     Range &
-    operator= (TOtherContainer &other)
+    operator= (TOtherContainer & other)
     {
         assign(*this, other);
         return *this;
@@ -116,7 +124,7 @@ public:
     // ------------------------------------------------------------------------
 
     template <typename TPos>
-   
+
     typename Reference<Range>::Type
     operator[] (TPos pos)
     {
@@ -124,7 +132,7 @@ public:
     }
 
     template <typename TPos>
-   
+
     typename GetValue<Range>::Type
     operator[] (TPos pos) const
     {
@@ -321,6 +329,14 @@ assign(Range<TIterator> &range, TContainer &cont)
     range.end = end(cont, Standard());
 }
 
+template <typename TIterator, typename TContainer>
+inline void
+assign(Range<TIterator> &range, TContainer const &cont)
+{
+    range.begin = begin(cont, Standard());
+    range.end = end(cont, Standard());
+}
+
 // ----------------------------------------------------------------------------
 // toRange()
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/basic/pair_packed.h b/include/seqan/basic/pair_packed.h
index b78d420..ce0c27b 100644
--- a/include/seqan/basic/pair_packed.h
+++ b/include/seqan/basic/pair_packed.h
@@ -78,9 +78,8 @@ struct Pair<T1, T2, Pack>
     // ------------------------------------------------------------------------
     // Members
     // ------------------------------------------------------------------------
-
-    T1 i1;
-    T2 i2;
+    T1 i1{};
+    T2 i2{};
 
     // ------------------------------------------------------------------------
     // Constructors
@@ -88,8 +87,22 @@ struct Pair<T1, T2, Pack>
 
     // Pair() = default; does not work on gcc4.9, it issues warnings if T1/T2
     // have no proper default constructor. >=gcc5.0 reports no warnings.
-    Pair() : i1(), i2() {};
+    // Caused by yara_indexer build, demo_tutorial_indices_base and
+    // demo_tutorial_index_iterators_index_bidirectional_search.
+#if defined(COMPILER_GCC) && (__GNUC__ <= 4)
+    Pair() : i1(T1()), i2(T2()) {};
+#else
+    Pair() = default;
+#endif
+
+    // NOTE(marehr) intel compiler bug in 17.x and 18.x: defaulted copy-constructor
+    // in classes with `#pragma pack(push, 1)` seg-faults. This leads to a
+    // seg-fault in yara-mapper (app test case yara).
+#if defined(COMPILER_LINTEL) || defined(COMPILER_WINTEL)
+    Pair(Pair const & p) : i1(p.i1), i2(p.i2) {};
+#else
     Pair(Pair const &) = default;
+#endif
     Pair(Pair &&) = default;
     ~Pair() = default;
     Pair & operator=(Pair const &) = default;
diff --git a/include/seqan/basic/profiling.h b/include/seqan/basic/profiling.h
index 63d1a20..4ca0dbe 100644
--- a/include/seqan/basic/profiling.h
+++ b/include/seqan/basic/profiling.h
@@ -37,6 +37,7 @@
 // TODO(holtgrew): This could use some cleanup.
 
 #include <ctime>
+#include <chrono>
 
 //SEQAN_NO_GENERATED_FORWARDS: no forwards are generated for this file
 
@@ -240,42 +241,11 @@ namespace seqan
  *
  * @see cpuTime
  */
-
-    #ifdef STDLIB_VS
-//        inline _proFloat sysTime() { return GetTickCount() * 1e-3; }
-        inline _proFloat sysTime() { return ( (_proFloat) clock() ) / CLOCKS_PER_SEC; }
-    #else
-
-        #include <unistd.h>
-        #if _POSIX_TIMERS > 0
-            #ifndef SEQAN_USE_CLOCKGETTIME
-            #define SEQAN_USE_CLOCKGETTIME
-            #endif
-        #endif
-
-        #ifndef SEQAN_USE_CLOCKGETTIME
-        /* some systems e.g. darwin have no clock_gettime */
-
-            #include <sys/time.h>
-
-            inline _proFloat sysTime() {
-                struct timeval tp;
-                gettimeofday(&tp, NULL);
-                return tp.tv_sec + tp.tv_usec * 1e-6;
-            }
-
-        #else
-
-            inline _proFloat sysTime() {
-                struct timespec tp;
-                clock_gettime(CLOCK_MONOTONIC, &tp);
-                return tp.tv_sec + tp.tv_nsec * 1e-9;
-            }
-
-        #endif
-
-    #endif
-
+    inline _proFloat sysTime()
+    {
+        return static_cast<_proFloat>(std::chrono::system_clock::now().time_since_epoch() /
+                                      std::chrono::duration<_proFloat>(1));
+    }
 
     struct ProfileFile_ {
 //IOREV not generic, uses FILE* instead of File() and custom IO
diff --git a/include/seqan/bed_io/bed_record.h b/include/seqan/bed_io/bed_record.h
index 0902fd1..084d400 100644
--- a/include/seqan/bed_io/bed_record.h
+++ b/include/seqan/bed_io/bed_record.h
@@ -89,7 +89,7 @@ typedef Tag<Bed12_> Bed12;
  * @var CharString BedRecord::ref;
  * @brief Name of the interval's reference name.
  *
- * @var int32_t BedRecord::beginPosition;
+ * @var int32_t BedRecord::beginPos;
  * @brief Begin position on the reference.
  *
  * @var int32_t BedRecord::rID;
@@ -99,7 +99,7 @@ typedef Tag<Bed12_> Bed12;
  * @brief Constant for invalid references.
  * @signature static const int32_t BedRecord::INVALID_REFID = -1;
  *
- * @var int32_t BedRecord::endPosition;
+ * @var int32_t BedRecord::endPos;
  * @brief End position on the reference.
  *
  * @var int32_t BedRecord::INVALID_POS;
diff --git a/include/seqan/find/find_myers_ukkonen.h b/include/seqan/find/find_myers_ukkonen.h
index 799596c..fc30f93 100644
--- a/include/seqan/find/find_myers_ukkonen.h
+++ b/include/seqan/find/find_myers_ukkonen.h
@@ -833,9 +833,9 @@ _myersAdjustBitmask(PatternState_<TNeedle, Myers<AlignTextBanded<TSpec, TFinderC
             state.bitMasks[ordValue(value)] |= (TWord)1 << (BitsPerValue<TWord>::VALUE - 1);
     }
 
-    if (IsSameType<TFinderCSP, NMatchesAll_>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TFinderCSP, NMatchesAll_>::VALUE)
         state.bitMasks[ordValue(unknownValue<TValue>())] |= (TWord)1 << (BitsPerValue<TWord>::VALUE - 1);
-    if (IsSameType<TFinderCSP, NMatchesNone_>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TFinderCSP, NMatchesNone_>::VALUE)
         state.bitMasks[ordValue(unknownValue<TValue>())] &= ~((TWord)1 << (BitsPerValue<TWord>::VALUE - 1));
 }
 
@@ -904,7 +904,7 @@ _myersGetBitmask(PatternState_<TNeedle, Myers<AlignTextBanded<TSpec, TFinderCSP,
     else
         res = 0;
 
-    if (IsSameType<TPatternCSP, NMatchesAll_>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TPatternCSP, NMatchesAll_>::VALUE)
     {
         ord = ordValue(unknownValue<TValue>());
         x = shift - state.shift[ord];
@@ -1301,7 +1301,7 @@ inline bool _findMyersLargePatterns (TFinder & finder,
         if ((largeState.scoreMask == largePattern.finalScoreMask) && (largeState.lastBlock == largePattern.blockCount - 1))
         {
             _setFinderEnd(finder);
-            if (IsSameType<TSpec, FindPrefix>::VALUE)
+            SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
             {
                 _setFinderLength(finder, endPosition(finder));
             }
@@ -1363,14 +1363,14 @@ _findMyersSmallPatterns(
         if (state.errors <= state.maxErrors)
         {
             _setFinderEnd(finder);
-            if (IsSameType<TSpec, FindPrefix>::VALUE)
+            SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
             {
                 _setFinderLength(finder, endPosition(finder));
             }
             return true;
         }
         //
-        // if (IsSameType<TSpec, FindPrefix>::VALUE)
+        // SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
         // {//limit haystack length during prefix search
         //
         // }
@@ -1481,7 +1481,7 @@ _findMyersSmallPatternsBanded(
                 state.VN0 = VN;
                 state.errors = errors;
                 _setFinderEnd(finder);
-                if (IsSameType<TSpec, FindPrefix>::VALUE)
+                SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
                 {
                     _setFinderLength(finder, endPosition(finder));
                 }
@@ -1542,7 +1542,7 @@ inline bool find (TFinder & finder,
         {
             goPrevious(finder);
             _setFinderEnd(finder);
-            if (IsSameType<TSpec, FindPrefix>::VALUE)
+            SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
             {
                 _setFinderLength(finder, endPosition(finder));
             }
@@ -1581,7 +1581,7 @@ inline bool find (TFinder & finder,
     typedef typename Haystack<TFinder>::Type THaystack;
     typedef typename Size<THaystack>::Type TSize;
 
-    TSize prefix_begin_position; //for prefix search: the position where the prefix begins
+    SEQAN_UNUSED TSize prefix_begin_position; //for prefix search: the position where the prefix begins
 
     if (empty(finder))
     {
@@ -1602,7 +1602,7 @@ inline bool find (TFinder & finder,
 
     TSize haystack_length = length(container(finder));
     // limit search width for prefix search
-    if (IsSameType<TSpec, FindPrefix>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
     {
         TSize maxlen = prefix_begin_position + pattern.needleSize - scoreLimit(state) + 1;
         if (haystack_length > maxlen)
diff --git a/include/seqan/find/find_score.h b/include/seqan/find/find_score.h
index bde4aa7..52d052e 100644
--- a/include/seqan/find/find_score.h
+++ b/include/seqan/find/find_score.h
@@ -311,7 +311,7 @@ inline void _patternInit (Pattern<TNeedle, DPSearch<TScore, TSpec, TFindBeginPat
         x += score_gap;
     }
 
-    if (IsSameType<TSpec, FindPrefix>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
     {//compute data_maxscore
         me.data_maxscore = 0;
         TNeedleIterator it = begin(needle(me), Standard());
@@ -375,12 +375,15 @@ _findScoreSimpleProportional(TFinder & finder, Pattern<TNeedle, DPSearch<TScore,
     TSize haystack_length = length(container(hostIterator(finder)));
 
     //limit search width for prefix search
-    if (IsSameType<TSpec, FindPrefix>::VALUE && (score_gap < 0))
+    SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
     {
-        TSize maxlen = prefix_begin_position + length(needle(me)) + ((scoreLimit(me) - me.data_maxscore) / score_gap) + 1;
-        if (haystack_length > maxlen)
+        if (score_gap < 0)
         {
-            haystack_length = maxlen;
+            TSize maxlen = prefix_begin_position + length(needle(me)) + ((scoreLimit(me) - me.data_maxscore) / score_gap) + 1;
+            if (haystack_length > maxlen)
+            {
+                haystack_length = maxlen;
+            }
         }
     }
 
@@ -424,7 +427,7 @@ _findScoreSimpleProportional(TFinder & finder, Pattern<TNeedle, DPSearch<TScore,
         if (*tab >= scoreLimit(me) )
         {//found a hit
             _setFinderEnd(finder);
-            if (IsSameType<TSpec, FindPrefix>::VALUE)
+            SEQAN_IF_CONSTEXPR (IsSameType<TSpec, FindPrefix>::VALUE)
             {
                 _setFinderLength(finder, endPosition(finder));
             }
diff --git a/include/seqan/index.h b/include/seqan/index.h
index b296116..3f7c205 100644
--- a/include/seqan/index.h
+++ b/include/seqan/index.h
@@ -233,6 +233,7 @@
 #include <seqan/index/find2_vstree_factory.h>
 #include <seqan/index/find2_index_multi.h>
 #include <seqan/index/find2_functors.h>
+#include <seqan/index/find2_index_approx.h>
 
 // ----------------------------------------------------------------------------
 // Lambda interface.
diff --git a/include/seqan/index/find2_backtracking.h b/include/seqan/index/find2_backtracking.h
index e51608a..b2a49a6 100644
--- a/include/seqan/index/find2_backtracking.h
+++ b/include/seqan/index/find2_backtracking.h
@@ -265,7 +265,7 @@ _updateVertexScore(TVertexScore current,
     TVertexScoreConstIterator previousIt = begin(previous, Standard());
 
     // Update first cell.
-    if (IsSameType<TStage, StageUpper_>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TStage, StageUpper_>::VALUE)
     {
         // C[0,j] = C[0,j-1] + 1 [Left]
         value(currentIt) = value(previousIt) + 1;
@@ -291,7 +291,7 @@ _updateVertexScore(TVertexScore current,
     }
 
     // Update last cell.
-    if (IsSameType<TStage, StageLower_>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TStage, StageLower_>::VALUE)
     {
         TScore score = ordEqual(textChar, value(patternIt)) ? 0 : 1;
 
diff --git a/include/seqan/index/find2_index_approx.h b/include/seqan/index/find2_index_approx.h
new file mode 100644
index 0000000..4139990
--- /dev/null
+++ b/include/seqan/index/find2_index_approx.h
@@ -0,0 +1,642 @@
+// ==========================================================================
+//                 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 NVIDIA Corporation 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 NVIDIA CORPORATION 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: Christopher Pockrandt <github at cpockrandt.de>
+// ==========================================================================
+// Approximate String matching via search schemes on a substring index.
+// ==========================================================================
+
+#ifndef SEQAN_INDEX_FIND2_INDEX_APPROX_H_
+#define SEQAN_INDEX_FIND2_INDEX_APPROX_H_
+
+namespace seqan {
+
+template <size_t N>
+struct OptimalSearch
+{
+    std::array<uint8_t, N> pi; // order of the blocks. permutation of [1..n]
+    std::array<uint8_t, N> l; // minimum number of errors at the end of the corresponding block
+    std::array<uint8_t, N> u; // maximum number of errors at the end of the corresponding block
+
+    std::array<uint32_t, N> blocklength; // cumulated values / prefix sums
+    uint32_t startPos;
+};
+
+template <size_t min, size_t max, typename TVoidType = void>
+struct OptimalSearchSchemes;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<0, 0, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<1>, 1> VALUE { {{ {{1}}, {{0}}, {{0}}, {{0}}, 0 }} };
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<1>, 1> OptimalSearchSchemes<0, 0, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<0, 1, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<2>, 2> VALUE
+    {{
+        { {{1, 2}}, {{0, 0}}, {{0, 1}}, {{0, 0}}, 0 },
+        { {{2, 1}}, {{0, 1}}, {{0, 1}}, {{0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<2>, 2> OptimalSearchSchemes<0, 1, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<0, 2, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<4>, 3> VALUE
+    {{
+        { {{2, 1, 3, 4}}, {{0, 0, 1, 1}}, {{0, 0, 2, 2}}, {{0, 0, 0, 0}}, 0 },
+        { {{3, 2, 1, 4}}, {{0, 0, 0, 0}}, {{0, 1, 1, 2}}, {{0, 0, 0, 0}}, 0 },
+        { {{4, 3, 2, 1}}, {{0, 0, 0, 2}}, {{0, 1, 2, 2}}, {{0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<4>, 3> OptimalSearchSchemes<0, 2, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<0, 3, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 2, 2}}, {{0, 0, 3, 3, 3}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{4, 3, 2, 1, 5}}, {{0, 0, 0, 0, 0}}, {{1, 1, 2, 2, 3}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 0, 3}}, {{0, 2, 2, 3, 3}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<0, 3, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<0, 4, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 0, 4}}, {{0, 3, 3, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{2, 3, 4, 5, 1}}, {{0, 0, 0, 0, 0}}, {{2, 2, 3, 3, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 3, 3}}, {{0, 0, 4, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<0, 4, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<1, 1, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<2>, 2> VALUE
+    {{
+        { {{1, 2}}, {{0, 1}}, {{0, 1}}, {{0, 0}}, 0 },
+        { {{2, 1}}, {{0, 1}}, {{0, 1}}, {{0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<2>, 2> OptimalSearchSchemes<1, 1, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<1, 2, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<4>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4}}, {{0, 0, 0, 2}}, {{0, 1, 2, 2}}, {{0, 0, 0, 0}}, 0 },
+        { {{2, 3, 4, 1}}, {{0, 0, 0, 1}}, {{0, 1, 1, 2}}, {{0, 0, 0, 0}}, 0 },
+        { {{4, 3, 2, 1}}, {{0, 0, 1, 1}}, {{0, 0, 2, 2}}, {{0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<4>, 3> OptimalSearchSchemes<1, 2, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<1, 3, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 2, 2}}, {{0, 0, 3, 3, 3}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{4, 3, 2, 1, 5}}, {{0, 0, 0, 0, 1}}, {{1, 1, 2, 2, 3}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 0, 3}}, {{0, 2, 2, 3, 3}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<1, 3, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<1, 4, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 0, 4}}, {{0, 3, 3, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{2, 3, 4, 5, 1}}, {{0, 0, 0, 0, 1}}, {{2, 2, 3, 3, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 3, 3}}, {{0, 0, 4, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<1, 4, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<2, 2, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<4>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4}}, {{0, 0, 0, 2}}, {{0, 1, 2, 2}}, {{0, 0, 0, 0}}, 0 },
+        { {{2, 3, 4, 1}}, {{0, 0, 1, 2}}, {{0, 1, 1, 2}}, {{0, 0, 0, 0}}, 0 },
+        { {{4, 3, 2, 1}}, {{0, 0, 0, 2}}, {{0, 0, 2, 2}}, {{0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<4>, 3> OptimalSearchSchemes<2, 2, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<2, 3, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 2, 2}}, {{0, 0, 3, 3, 3}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{4, 3, 2, 1, 5}}, {{0, 0, 0, 0, 2}}, {{1, 1, 2, 2, 3}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 0, 3}}, {{0, 2, 2, 3, 3}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<2, 3, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<2, 4, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 0, 4}}, {{0, 3, 3, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{2, 3, 4, 5, 1}}, {{0, 0, 0, 0, 2}}, {{2, 2, 3, 3, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 3, 3}}, {{0, 0, 4, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<2, 4, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<3, 3, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 2, 3}}, {{0, 0, 3, 3, 3}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{4, 3, 2, 1, 5}}, {{0, 0, 0, 0, 3}}, {{1, 1, 2, 2, 3}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 0, 3}}, {{0, 2, 2, 3, 3}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<3, 3, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<3, 4, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 0, 4}}, {{0, 3, 3, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{2, 3, 4, 5, 1}}, {{0, 0, 0, 0, 3}}, {{2, 2, 3, 3, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 3, 3}}, {{0, 0, 4, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<3, 4, TVoidType>::VALUE;
+
+template <typename TVoidType>
+struct OptimalSearchSchemes<4, 4, TVoidType>
+{
+    static constexpr std::array<OptimalSearch<5>, 3> VALUE
+    {{
+        { {{1, 2, 3, 4, 5}}, {{0, 0, 0, 0, 4}}, {{0, 3, 3, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{2, 3, 4, 5, 1}}, {{0, 0, 0, 0, 4}}, {{2, 2, 3, 3, 4}}, {{0, 0, 0, 0, 0}}, 0 },
+        { {{5, 4, 3, 2, 1}}, {{0, 0, 0, 3, 4}}, {{0, 0, 4, 4, 4}}, {{0, 0, 0, 0, 0}}, 0 }
+    }};
+};
+
+template <typename TVoidType>
+constexpr std::array<OptimalSearch<5>, 3> OptimalSearchSchemes<4, 4, TVoidType>::VALUE;
+
+// Given the blocklengths (absolute, not cumulative values), assign it to all
+// OptimalSearches in a OptimalSearchScheme. The order of blocklength has to be from left to
+// right (regarding blocks)
+template <size_t nbrBlocks, size_t N>
+inline void _optimalSearchSchemeSetBlockLength(std::array<OptimalSearch<nbrBlocks>, N> & ss,
+                                               std::vector<uint32_t> const & blocklength)
+{
+    for (OptimalSearch<nbrBlocks> & s : ss)
+        for (uint8_t i = 0; i < s.blocklength.size(); ++i)
+            s.blocklength[i] = blocklength[s.pi[i]-1] + ((i > 0) ? s.blocklength[i-1] : 0);
+}
+
+// requires blocklength to be already set!
+template <size_t nbrBlocks, size_t N>
+inline void _optimalSearchSchemeInit(std::array<OptimalSearch<nbrBlocks>, N> & ss)
+{
+    // check whether 2nd block is on the left or right and choose initialDirection accordingly
+    // (more efficient since we do not have to switch directions and thus have better caching performance)
+    // for that we need to slightly modify search()
+    for (OptimalSearch<nbrBlocks> & s : ss)
+    {
+        s.startPos = 0;
+        for (uint8_t i = 0; i < s.pi.size(); ++i)
+            if (s.pi[i] < s.pi[0])
+                s.startPos += s.blocklength[i] - ((i > 0) ? s.blocklength[i-1] : 0);
+    }
+}
+
+template <size_t nbrBlocks, size_t N>
+inline void _optimalSearchSchemeComputeFixedBlocklength(std::array<OptimalSearch<nbrBlocks>, N> & ss, uint32_t const needleLength)
+{
+    uint8_t blocks = ss[0].pi.size();
+    uint32_t blocklength = needleLength / blocks;
+    uint8_t rest = needleLength - blocks * blocklength;
+    std::vector<uint32_t> blocklengths;
+    for (uint8_t i = 0; i < blocks; ++i)
+        blocklengths.push_back(blocklength + (i < rest));
+
+    _optimalSearchSchemeSetBlockLength(ss, blocklengths);
+    _optimalSearchSchemeInit(ss);
+}
+
+template <typename TDelegate,
+          typename TText, typename TIndex, typename TIndexSpec,
+          typename TNeedle,
+          size_t nbrBlocks,
+          typename TDir>
+inline void _optimalSearchSchemeDeletion(TDelegate & delegate,
+                                         Iter<Index<TText, BidirectionalIndex<TIndex> >, VSTree<TopDown<TIndexSpec> > > iter,
+                                         TNeedle const & needle,
+                                         uint32_t const needleLeftPos,
+                                         uint32_t const needleRightPos,
+                                         uint8_t const errors,
+                                         OptimalSearch<nbrBlocks> const & s,
+                                         uint8_t const blockIndex,
+                                         TDir const & /**/)
+{
+    uint8_t const maxErrorsLeftInBlock = s.u[blockIndex] - errors;
+    uint8_t const minErrorsLeftInBlock = (s.l[blockIndex] > errors) ? (s.l[blockIndex] - errors) : 0;
+
+    if (minErrorsLeftInBlock == 0)
+    {
+        uint8_t const blockIndex2 = std::min(blockIndex + 1, static_cast<uint8_t>(s.u.size()) - 1);
+        bool const goToRight2 = s.pi[blockIndex2] > s.pi[blockIndex2 - 1];
+
+        if (goToRight2)
+        {
+            _optimalSearchScheme(delegate, iter, needle, needleLeftPos, needleRightPos, errors, s, blockIndex2, Rev(),
+                                 EditDistance());
+        }
+        else
+        {
+            _optimalSearchScheme(delegate, iter, needle, needleLeftPos, needleRightPos, errors, s, blockIndex2, Fwd(),
+                                 EditDistance());
+        }
+    }
+
+    if (maxErrorsLeftInBlock > 0 && goDown(iter, TDir()))
+    {
+        do
+        {
+            _optimalSearchSchemeDeletion(delegate, iter, needle, needleLeftPos, needleRightPos, errors + 1, s,
+                                         blockIndex, TDir());
+        } while (goRight(iter, TDir()));
+    }
+}
+
+template <typename TDelegate,
+          typename TText, typename TIndex, typename TIndexSpec,
+          typename TNeedle,
+          size_t nbrBlocks,
+          typename TDir,
+          typename TDistanceTag>
+inline void _optimalSearchSchemeChildren(TDelegate & delegate,
+                                         Iter<Index<TText, BidirectionalIndex<TIndex> >, VSTree<TopDown<TIndexSpec> > > iter,
+                                         TNeedle const & needle,
+                                         uint32_t const needleLeftPos,
+                                         uint32_t const needleRightPos,
+                                         uint8_t const errors,
+                                         OptimalSearch<nbrBlocks> const & s,
+                                         uint8_t const blockIndex,
+                                         uint8_t const minErrorsLeftInBlock,
+                                         TDir const & /**/,
+                                         TDistanceTag const & /**/)
+{
+    bool goToRight = std::is_same<TDir, Rev>::value;
+    if (goDown(iter, TDir()))
+    {
+        uint32_t charsLeft = s.blocklength[blockIndex] - (needleRightPos - needleLeftPos - 1);
+        do
+        {
+            bool delta = !ordEqual(parentEdgeLabel(iter, TDir()),
+                                   needle[goToRight ? needleRightPos - 1 : needleLeftPos - 1]);
+
+            // NOTE (cpockrandt): this might not be optimal yet! we have more edges than in the theoretical model,
+            // since we go down an edge before we check whether it can even work out!
+            if (!std::is_same<TDistanceTag, EditDistance>::value && minErrorsLeftInBlock > 0 &&
+                charsLeft + delta < minErrorsLeftInBlock + 1u) // charsLeft - 1 < minErrorsLeftInBlock - delta
+            {
+                continue;
+            }
+
+            int32_t needleLeftPos2 = needleLeftPos - !goToRight;
+            uint32_t needleRightPos2 = needleRightPos + goToRight;
+
+            if (needleRightPos - needleLeftPos == s.blocklength[blockIndex])
+            {
+                // leave the possibility for one or multiple deletions! therefore, don't change direction, etc!
+                if (std::is_same<TDistanceTag, EditDistance>::value)
+                {
+                    _optimalSearchSchemeDeletion(delegate, iter, needle, needleLeftPos2, needleRightPos2,
+                                                 errors + delta, s, blockIndex, TDir());
+                }
+                else
+                {
+                    uint8_t blockIndex2 = std::min(blockIndex + 1, static_cast<uint8_t>(s.u.size()) - 1);
+                    bool goToRight2 = s.pi[blockIndex2] > s.pi[blockIndex2 - 1];
+                    if (goToRight2)
+                    {
+                        _optimalSearchScheme(delegate, iter, needle, needleLeftPos2, needleRightPos2, errors + delta, s,
+                                             blockIndex2, Rev(), TDistanceTag());
+                    }
+                    else
+                    {
+                        _optimalSearchScheme(delegate, iter, needle, needleLeftPos2, needleRightPos2, errors + delta, s,
+                                             blockIndex2, Fwd(), TDistanceTag());
+                    }
+                }
+            }
+            else
+            {
+                _optimalSearchScheme(delegate, iter, needle, needleLeftPos2, needleRightPos2, errors + delta, s,
+                                     blockIndex, TDir(), TDistanceTag());
+            }
+
+            // Deletion
+            if (std::is_same<TDistanceTag, EditDistance>::value)
+            {
+                _optimalSearchScheme(delegate, iter, needle, needleLeftPos, needleRightPos, errors + 1, s, blockIndex,
+                                     TDir(), TDistanceTag());
+            }
+        } while (goRight(iter, TDir()));
+    }
+}
+
+template <typename TDelegate,
+          typename TText, typename TIndex, typename TIndexSpec,
+          typename TNeedle,
+          size_t nbrBlocks,
+          typename TDir,
+          typename TDistanceTag>
+inline void _optimalSearchSchemeExact(TDelegate & delegate,
+                                      Iter<Index<TText, BidirectionalIndex<TIndex> >, VSTree<TopDown<TIndexSpec> > > iter,
+                                      TNeedle const & needle,
+                                      uint32_t const needleLeftPos,
+                                      uint32_t const needleRightPos,
+                                      uint8_t const errors,
+                                      OptimalSearch<nbrBlocks> const & s,
+                                      uint8_t const blockIndex,
+                                      TDir const & /**/,
+                                      TDistanceTag const & /**/)
+{
+    bool goToRight2 = (blockIndex < s.pi.size() - 1) && s.pi[blockIndex + 1] > s.pi[blockIndex];
+    if (std::is_same<TDir, Rev>::value)
+    {
+        uint32_t infixPosLeft = needleRightPos - 1;
+        uint32_t infixPosRight = needleLeftPos + s.blocklength[blockIndex] - 1;
+
+        if (!goDown(iter, infix(needle, infixPosLeft, infixPosRight + 1), TDir()))
+            return;
+
+        if (goToRight2)
+        {
+            _optimalSearchScheme(delegate, iter, needle, needleLeftPos, infixPosRight + 2, errors, s,
+                                 std::min(blockIndex + 1, static_cast<uint8_t>(s.u.size()) - 1), Rev(), TDistanceTag());
+        }
+        else
+        {
+            _optimalSearchScheme(delegate, iter, needle, needleLeftPos, infixPosRight + 2, errors, s,
+                                 std::min(blockIndex + 1, static_cast<uint8_t>(s.u.size()) - 1), Fwd(), TDistanceTag());
+        }
+    }
+    else
+    {
+        // has to be signed, otherwise we run into troubles when checking for -1 >= 0u
+        int32_t infixPosLeft = needleRightPos - s.blocklength[blockIndex] - 1;
+        int32_t infixPosRight = needleLeftPos - 1;
+
+        while (infixPosRight >= infixPosLeft)
+        {
+            if (!goDown(iter, needle[infixPosRight], TDir()))
+                return;
+            --infixPosRight;
+        }
+        if (goToRight2)
+        {
+            _optimalSearchScheme(delegate, iter, needle, infixPosLeft, needleRightPos, errors, s,
+                                 std::min(blockIndex + 1, static_cast<uint8_t>(s.u.size()) - 1), Rev(), TDistanceTag());
+        }
+        else
+        {
+            _optimalSearchScheme(delegate, iter, needle, infixPosLeft, needleRightPos, errors, s,
+                                 std::min(blockIndex + 1, static_cast<uint8_t>(s.u.size()) - 1), Fwd(), TDistanceTag());
+        }
+    }
+}
+
+template <typename TDelegate,
+          typename TText, typename TIndex, typename TIndexSpec,
+          typename TNeedle,
+          size_t nbrBlocks,
+          typename TDir,
+          typename TDistanceTag>
+inline void _optimalSearchScheme(TDelegate & delegate,
+                                 Iter<Index<TText, BidirectionalIndex<TIndex> >, VSTree<TopDown<TIndexSpec> > > iter,
+                                 TNeedle const & needle,
+                                 uint32_t const needleLeftPos,
+                                 uint32_t const needleRightPos,
+                                 uint8_t const errors,
+                                 OptimalSearch<nbrBlocks> const & s,
+                                 uint8_t const blockIndex,
+                                 TDir const & /**/,
+                                 TDistanceTag const & /**/)
+{
+    uint8_t const maxErrorsLeftInBlock = s.u[blockIndex] - errors;
+    uint8_t const minErrorsLeftInBlock = (s.l[blockIndex] > errors) ? (s.l[blockIndex] - errors) : 0;
+
+    // Done.
+    if (minErrorsLeftInBlock == 0 && needleLeftPos == 0 && needleRightPos == length(needle) + 1)
+    {
+        delegate(iter, needle, errors);
+    }
+    // Exact search in current block.
+    else if (maxErrorsLeftInBlock == 0 && needleRightPos - needleLeftPos - 1 != s.blocklength[blockIndex])
+    {
+        _optimalSearchSchemeExact(delegate, iter, needle, needleLeftPos, needleRightPos, errors, s, blockIndex, TDir(),
+                                  TDistanceTag());
+    }
+    // Approximate search in current block.
+    // (s.blocklength[blockIndex]-(needleRightPos-needleLeftPos-(needleLeftPos!=needleRightPos))>=minErrorsLeftInBlock)
+    else
+    {
+        // Insertion
+        if (std::is_same<TDistanceTag, EditDistance>::value)
+        {
+            bool const goToRight = std::is_same<TDir, Rev>::value;
+            int32_t const needleLeftPos2 = needleLeftPos - !goToRight;
+            uint32_t const needleRightPos2 = needleRightPos + goToRight;
+
+            if (needleRightPos - needleLeftPos == s.blocklength[blockIndex])
+            {
+                // leave the possibility for one or multiple deletions! therefore, don't change direction, etc!
+                _optimalSearchSchemeDeletion(delegate, iter, needle, needleLeftPos2, needleRightPos2, errors + 1, s,
+                                             blockIndex, TDir());
+            }
+            else
+            {
+                _optimalSearchScheme(delegate, iter, needle, needleLeftPos2, needleRightPos2, errors + 1, s, blockIndex,
+                                     TDir(), TDistanceTag());
+            }
+        }
+        _optimalSearchSchemeChildren(delegate, iter, needle, needleLeftPos, needleRightPos, errors, s, blockIndex,
+                                     minErrorsLeftInBlock, TDir(), TDistanceTag());
+    }
+}
+
+template <typename TDelegate,
+          typename TText, typename TIndex, typename TIndexSpec,
+          typename TNeedle,
+          size_t nbrBlocks,
+          typename TDistanceTag>
+inline void _optimalSearchScheme(TDelegate & delegate,
+                                 Iter<Index<TText, BidirectionalIndex<TIndex> >, VSTree<TopDown<TIndexSpec> > > it,
+                                 TNeedle const & needle,
+                                 OptimalSearch<nbrBlocks> const & s,
+                                 TDistanceTag const & /**/)
+{
+    _optimalSearchScheme(delegate, it, needle, s.startPos, s.startPos + 1, 0, s, 0, Rev(), TDistanceTag());
+}
+
+template <typename TDelegate,
+          typename TText, typename TIndex, typename TIndexSpec,
+          typename TNeedle,
+          size_t nbrBlocks, size_t N,
+          typename TDistanceTag>
+inline void _optimalSearchScheme(TDelegate & delegate,
+                                 Iter<Index<TText, BidirectionalIndex<TIndex> >, VSTree<TopDown<TIndexSpec> > > it,
+                                 TNeedle const & needle,
+                                 std::array<OptimalSearch<nbrBlocks>, N> const & ss,
+                                 TDistanceTag const & /**/)
+{
+    for (auto & s : ss)
+        _optimalSearchScheme(delegate, it, needle, s, TDistanceTag());
+}
+
+// ----------------------------------------------------------------------------
+// Function find()
+// ----------------------------------------------------------------------------
+
+template <size_t minErrors, size_t maxErrors,
+          typename TDelegate,
+          typename TText, typename TIndexSpec,
+          typename TChar, typename TStringSpec,
+          typename TDistanceTag>
+inline void
+find(TDelegate & delegate,
+     Index<TText, BidirectionalIndex<TIndexSpec> > & index,
+     String<TChar, TStringSpec> const & needle,
+     TDistanceTag const & /**/)
+{
+    auto scheme = OptimalSearchSchemes<minErrors, maxErrors>::VALUE;
+    _optimalSearchSchemeComputeFixedBlocklength(scheme, length(needle));
+    Iter<Index<TText, BidirectionalIndex<TIndexSpec> >, VSTree<TopDown<> > > it(index);
+    _optimalSearchScheme(delegate, it, needle, scheme, TDistanceTag());
+}
+
+// ----------------------------------------------------------------------------
+// Function find()
+// ----------------------------------------------------------------------------
+
+template <size_t minErrors, size_t maxErrors,
+          typename TDelegate,
+          typename TText, typename TIndexSpec,
+          typename TNeedle, typename TStringSetSpec,
+          typename TDistanceTag,
+          typename TParallelTag>
+inline void
+find(TDelegate & delegate,
+     Index<TText, BidirectionalIndex<TIndexSpec> > & index,
+     StringSet<TNeedle, TStringSetSpec> const & needles,
+     TDistanceTag const & /**/,
+     TParallelTag const & /**/)
+{
+    typedef typename Iterator<StringSet<TNeedle, TStringSetSpec> const, Rooted>::Type TNeedleIt;
+    typedef typename Reference<TNeedleIt>::Type                                       TNeedleRef;
+    iterate(needles, [&](TNeedleIt const & needleIt)
+    {
+        TNeedleRef needle = value(needleIt);
+        find<minErrors, maxErrors>(delegate, index, needle, TDistanceTag());
+    },
+    Rooted(), TParallelTag());
+}
+
+// ----------------------------------------------------------------------------
+// Function find()
+// ----------------------------------------------------------------------------
+
+template <size_t minErrors, size_t maxErrors,
+          typename TDelegate,
+          typename TText, typename TIndexSpec,
+          typename TNeedle, typename TStringSetSpec,
+          typename TDistanceTag>
+inline void
+find(TDelegate & delegate,
+     Index<TText, BidirectionalIndex<TIndexSpec> > & index,
+     StringSet<TNeedle, TStringSetSpec> const & needles,
+     TDistanceTag const & /**/)
+{
+    find<minErrors, maxErrors>(delegate, index, needles, TDistanceTag(), Serial());
+}
+
+}
+
+#endif  // #ifndef SEQAN_INDEX_FIND2_INDEX_APPROX_H_
diff --git a/include/seqan/index/find_index_lambda.h b/include/seqan/index/find_index_lambda.h
index a39d498..14f356b 100644
--- a/include/seqan/index/find_index_lambda.h
+++ b/include/seqan/index/find_index_lambda.h
@@ -112,7 +112,7 @@ _findBacktracking(TIndexIt indexIt,
         else
         {
             // Insertion.
-            if (IsSameType<TDistance, EditDistance>::VALUE)
+            SEQAN_IF_CONSTEXPR (IsSameType<TDistance, EditDistance>::VALUE)
             {
                 _findBacktracking(indexIt, needle, needleIt + 1,
                                   static_cast<TThreshold>(errors + 1), threshold, delegate, TDistance());
@@ -128,7 +128,7 @@ _findBacktracking(TIndexIt indexIt,
                                       static_cast<TThreshold>(errors + delta), threshold, delegate, TDistance());
 
                     // Deletion.
-                    if (IsSameType<TDistance, EditDistance>::VALUE)
+                    SEQAN_IF_CONSTEXPR (IsSameType<TDistance, EditDistance>::VALUE)
                     {
                         _findBacktracking(indexIt, needle, needleIt,
                                           static_cast<TThreshold>(errors + 1), threshold, delegate, TDistance());
diff --git a/include/seqan/index/find_index_qgram.h b/include/seqan/index/find_index_qgram.h
index bd50496..2c61d20 100644
--- a/include/seqan/index/find_index_qgram.h
+++ b/include/seqan/index/find_index_qgram.h
@@ -80,7 +80,7 @@ namespace seqan
         TDir const &dir = indexDir(index);
         TShape &shape = indexShape(index);
 
-        if (IsSameType<TBucketMap, Nothing>::VALUE)
+        SEQAN_IF_CONSTEXPR (IsSameType<TBucketMap, Nothing>::VALUE)
         {
             // hashUpper and patterns shorter than the shape can only be used for
             // direct addressing q-gram indices
diff --git a/include/seqan/index/index_base.h b/include/seqan/index/index_base.h
index 1cb2eb8..6aa2f5b 100644
--- a/include/seqan/index/index_base.h
+++ b/include/seqan/index/index_base.h
@@ -218,7 +218,7 @@ SEQAN_CONCEPT_REFINE(StringTrieConcept, (TIndex), (StringIndexConcept)) {};
  */
 
     template <typename TObject>
-    struct [[deprecated("Deprecated in favor of StringSpec.")]] DefaultIndexStringSpec : StringSpec<TObject> {};
+    struct DefaultIndexStringSpec : StringSpec<TObject> {};
 
 
 //////////////////////////////////////////////////////////////////////////////
diff --git a/include/seqan/index/index_esa_stree.h b/include/seqan/index/index_esa_stree.h
index 60cfbf3..1096ad9 100644
--- a/include/seqan/index/index_esa_stree.h
+++ b/include/seqan/index/index_esa_stree.h
@@ -1533,7 +1533,7 @@ SEQAN_CONCEPT_IMPL((Index<TText, IndexEsa<TSpec> > const), (StringTreeConcept));
 
         typename Iterator<Index<TText, TIndexSpec>, TSpec>::Type it(index);
 
-        if (IsSameType<typename TTraits::DfsOrder, Postorder_>::VALUE) {
+        SEQAN_IF_CONSTEXPR (IsSameType<typename TTraits::DfsOrder, Postorder_>::VALUE) {
             while (goDown(it)) ;
         }
 
@@ -1582,7 +1582,7 @@ SEQAN_CONCEPT_IMPL((Index<TText, IndexEsa<TSpec> > const), (StringTreeConcept));
 
         goRoot(it);
 
-        if (IsSameType<typename TTraits::DfsOrder, Postorder_>::VALUE) {
+        SEQAN_IF_CONSTEXPR (IsSameType<typename TTraits::DfsOrder, Postorder_>::VALUE) {
             while (goDown(it)) ;
             return;
         }
diff --git a/include/seqan/index/index_fm_compressed_sa.h b/include/seqan/index/index_fm_compressed_sa.h
index 16fbc0c..453fdd3 100644
--- a/include/seqan/index/index_fm_compressed_sa.h
+++ b/include/seqan/index/index_fm_compressed_sa.h
@@ -84,8 +84,8 @@ typedef Tag<FibreSparseString_> const FibreSparseString;
 // ----------------------------------------------------------------------------
 
 template <typename TText, typename TSpec, typename TConfig>
-struct StringSpec<CompressedSA<TText, TSpec, TConfig> > :
-    StringSpec<TText> {};
+struct DefaultIndexStringSpec<CompressedSA<TText, TSpec, TConfig> > :
+    DefaultIndexStringSpec<TText> {};
 
 // ----------------------------------------------------------------------------
 // Metafunction Fibre
@@ -97,7 +97,7 @@ struct Fibre<CompressedSA<TText, TSpec, TConfig>, FibreSparseString>
     // TODO(esiragusa): Change SparseString spec to be SparseString<TValue, TSpec, TConfig>.
     typedef CompressedSA<TText, TSpec, TConfig>         TCSA;
     typedef typename SAValue<TText>::Type               TSAValue_;
-    typedef typename StringSpec<TCSA>::Type TSASpec_;
+    typedef typename DefaultIndexStringSpec<TCSA>::Type TSASpec_;
     typedef String<TSAValue_, TSASpec_>                 TSA_;
     typedef SparseString<TSA_, TConfig>                 Type;
 };
diff --git a/include/seqan/index/index_fm_lf_table.h b/include/seqan/index/index_fm_lf_table.h
index 8da0a12..1591e20 100644
--- a/include/seqan/index/index_fm_lf_table.h
+++ b/include/seqan/index/index_fm_lf_table.h
@@ -125,7 +125,7 @@ struct Fibre<LF<TText, TSpec, TConfig>, FibrePrefixSums>
 //    typedef Tuple<TSize_, ValueSize<TValue_>::VALUE>          Type;
 
     typedef typename Size<LF<TText, TSpec, TConfig> >::Type TSize_;
-    typedef typename StringSpec<TText>::Type                TSpec_;
+    typedef typename DefaultIndexStringSpec<TText>::Type    TSpec_;
     typedef String<TSize_,  TSpec_>                         Type;
 };
 
@@ -494,13 +494,36 @@ _getCumulativeBwtRank(LF<TText, TSpec, TConfig> const & lf, TPos pos, TValue val
 // ----------------------------------------------------------------------------
 
 template <typename TText, typename TSpec, typename TConfig, typename TPos>
-inline
-typename Size<LF<TText, TSpec, TConfig> const>::Type
+inline std::enable_if_t<!isWaveletTree<typename TConfig::Bwt>::Value, typename Size<LF<TText, TSpec, TConfig> >::Type>
 _getBwtRank(LF<TText, TSpec, TConfig> const & lf, TPos pos)
 {
     return _getBwtRank(lf, pos, getValue(lf.bwt, pos));
 }
 
+template <typename TText, typename TSpec, typename TConfig, typename TPos>
+inline std::enable_if_t<isWaveletTree<typename TConfig::Bwt>::Value, typename Size<LF<TText, TSpec, TConfig> >::Type>
+_getBwtRank(LF<TText, TSpec, TConfig> const & lf, TPos pos)
+{
+    typedef typename Value<LF<TText, TSpec, TConfig> >::Type    TChar;
+    typedef typename Size<LF<TText, TSpec, TConfig> >::Type     TSize;
+
+    TChar val;
+    TSize rank = 0;
+
+    if (pos > 0)
+    {
+        rank = _getRankAndValue(lf.bwt, pos - 1, val);
+
+        if (ordEqual(lf.sentinelSubstitute, val))
+            rank -= _getSentinelsRank(lf, pos - 1);
+    }
+    else
+    {
+        val = getValue(lf.bwt, pos);
+    }
+    return rank + _getPrefixSum(lf, val);
+}
+
 template <typename TText, typename TSpec, typename TConfig, typename TPos, typename TValue>
 inline
 typename Size<LF<TText, TSpec, TConfig> >::Type
@@ -672,8 +695,36 @@ _createBwt(LF<StringSet<TText, TSSetSpec>, TSpec, TConfig> & lf, TBwt & bwt, TOt
  * @return TReturn Returns a <tt>bool</tt> which is <tt>true</tt> on successes and <tt>false</tt> otherwise.
  */
 // This function creates all table of the lf table given a text and a suffix array.
+
+template <typename TText, typename TSpec, typename TConfig, typename TOtherText, typename TSA>
+inline std::enable_if_t<!isWaveletTree<typename TConfig::Bwt>::Value, void>
+createLF(LF<TText, TSpec, TConfig> & lf, TOtherText const & text, TSA const & sa)
+{
+    typedef LF<TText, TSpec, TConfig>                          TLF;
+    typedef typename Value<TLF>::Type                          TValue;
+    typedef typename Size<TLF>::Type                           TSize;
+
+    // Clear assuming undefined state.
+    clear(lf);
+
+    // Compute prefix sum.
+    prefixSums<TValue>(lf.sums, text);
+
+    // Choose the sentinel substitute.
+    _setSentinelSubstitute(lf);
+
+    // Create and index BWT bwt for rank queries.
+    createRankDictionary(lf, text, sa);
+
+    // Add sentinels to prefix sum.
+    TSize sentinelsCount = countSequences(text);
+    for (TSize i = 0; i < length(lf.sums); ++i)
+        lf.sums[i] += sentinelsCount;
+}
+
 template <typename TText, typename TSpec, typename TConfig, typename TOtherText, typename TSA>
-inline void createLF(LF<TText, TSpec, TConfig> & lf, TOtherText const & text, TSA const & sa)
+inline std::enable_if_t<isWaveletTree<typename TConfig::Bwt>::Value, void>
+createLF(LF<TText, TSpec, TConfig> & lf, TOtherText const & text, TSA const & sa)
 {
     typedef LF<TText, TSpec, TConfig>                          TLF;
     typedef typename Fibre<TLF, FibreTempBwt>::Type            TBwt;
diff --git a/include/seqan/index/index_fm_rank_dictionary_base.h b/include/seqan/index/index_fm_rank_dictionary_base.h
index 6d8a5ba..1b3425b 100644
--- a/include/seqan/index/index_fm_rank_dictionary_base.h
+++ b/include/seqan/index/index_fm_rank_dictionary_base.h
@@ -38,6 +38,13 @@
 namespace seqan {
 
 // ============================================================================
+// Forwards
+// ============================================================================
+
+template <typename TText, typename TSpec, typename TConfig>
+struct LF;
+
+// ============================================================================
 // Tags
 // ============================================================================
 
@@ -121,7 +128,7 @@ struct RankDictionary;
 // ----------------------------------------------------------------------------
 
 template <typename TValue, template <typename, typename> class TRankDictionary, typename TSpec, typename TConfig>
-struct StringSpec<RankDictionary<TValue, TRankDictionary<TSpec, TConfig> > >
+struct DefaultIndexStringSpec<RankDictionary<TValue, TRankDictionary<TSpec, TConfig> > >
 {
     typedef typename TConfig::Fibre Type;
 };
@@ -261,6 +268,85 @@ createRankDictionary(RankDictionary<TValue, TSpec> & dict, TText const & text)
     updateRanks(dict);
 }
 
+template <typename TText, typename TSpec, typename TConfig, typename TOtherText, typename TSA>
+inline void
+createRankDictionary(LF<TText, TSpec, TConfig> & lf, TOtherText const & text, TSA const & sa)
+{
+    typedef typename GetValue<TSA>::Type                    TSAValue;
+    typedef typename Size<TSA>::Type                        TSize;
+
+    // Resize the RankDictionary.
+    resize(lf.bwt, lengthSum(text) + 1, Exact());
+
+    // Assign the text value by value.
+    setValue(lf.bwt, 0, back(text));
+
+    for (TSize i = 0; i < length(sa); ++i)
+    {
+        TSAValue pos = sa[i];
+
+        if (pos != 0)
+        {
+            setValue(lf.bwt, i + 1, getValue(text, pos - 1));
+        }
+        else
+        {
+            setValue(lf.bwt, i + 1, lf.sentinelSubstitute);
+            lf.sentinels = i + 1;
+        }
+    }
+
+   // Update all ranks.
+   updateRanks(lf.bwt);
+}
+
+template <typename TText, typename TSSetSpec, typename TSpec, typename TConfig, typename TOtherText, typename TSA>
+inline void
+createRankDictionary(LF<StringSet<TText, TSSetSpec>, TSpec, TConfig> & lf, TOtherText const & text, TSA const & sa)
+{
+    typedef typename Value<TSA>::Type                       TSAValue;
+    typedef typename Size<TSA>::Type                        TSize;
+
+    // Resize the RankDictionary.
+    TSize seqNum = countSequences(text);
+    TSize totalLen = lengthSum(text);
+    resize(lf.sentinels, seqNum + totalLen, Exact());
+    resize(lf.bwt, seqNum + totalLen, Exact());
+
+    // Fill the sentinel positions (they are all at the beginning of the bwt).
+    for (TSize i = 0; i < seqNum; ++i)
+    {
+        if (length(text[seqNum - (i + 1)]) > 0)
+        {
+            setValue(lf.bwt, i, back(text[seqNum - (i + 1)]));
+            setValue(lf.sentinels, i, false);
+        }
+    }
+
+    // Compute the rest of the bwt.
+    for (TSize i = 0; i < length(sa); ++i)
+    {
+        TSAValue pos;    // = SA[i];
+        posLocalize(pos, sa[i], stringSetLimits(text));
+
+        if (getSeqOffset(pos) != 0)
+        {
+            setValue(lf.bwt, i + seqNum, getValue(getValue(text, getSeqNo(pos)), getSeqOffset(pos) - 1));
+            setValue(lf.sentinels, i + seqNum, false);
+        }
+        else
+        {
+            setValue(lf.bwt, i + seqNum, lf.sentinelSubstitute);
+            setValue(lf.sentinels, i + seqNum, true);
+        }
+    }
+
+   // Update all ranks.
+   updateRanks(lf.bwt);
+   // Update the auxiliary RankDictionary of sentinel positions.
+   updateRanks(lf.sentinels);
+}
+
 // ----------------------------------------------------------------------------
 // Function getRank()
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/index/index_fm_rank_dictionary_levels.h b/include/seqan/index/index_fm_rank_dictionary_levels.h
index 8b0a446..2eeeadd 100644
--- a/include/seqan/index/index_fm_rank_dictionary_levels.h
+++ b/include/seqan/index/index_fm_rank_dictionary_levels.h
@@ -354,7 +354,7 @@ struct Fibre<RankDictionary<TValue, Levels<TSpec, TConfig> >, FibreRanks>
 {
     typedef RankDictionary<TValue, Levels<TSpec, TConfig> >         TRankDictionary_;
     typedef RankDictionaryEntry_<TValue, Levels<TSpec, TConfig> >   TEntry_;
-    typedef typename StringSpec<TRankDictionary_>::Type             TFibreSpec_;
+    typedef typename DefaultIndexStringSpec<TRankDictionary_>::Type TFibreSpec_;
 
     typedef String<TEntry_, TFibreSpec_>                            Type;
 };
@@ -364,7 +364,7 @@ struct Fibre<RankDictionary<TValue, Levels<TSpec, TConfig> >, FibreSuperBlocks>
 {
     typedef RankDictionary<TValue, Levels<TSpec, TConfig> >                             TRankDictionary_;
     typedef typename RankDictionarySuperBlock_<TValue, Levels<TSpec, TConfig> >::Type   TSuperBlocks_;
-    typedef typename StringSpec<TRankDictionary_>::Type                                 TFibreSpec_;
+    typedef typename DefaultIndexStringSpec<TRankDictionary_>::Type                     TFibreSpec_;
 
     typedef String<TSuperBlocks_, TFibreSpec_>                                          Type;
 };
@@ -374,7 +374,7 @@ struct Fibre<RankDictionary<TValue, Levels<TSpec, TConfig> >, FibreUltraBlocks>
 {
     typedef RankDictionary<TValue, Levels<TSpec, TConfig> >                             TRankDictionary_;
     typedef typename RankDictionaryUltraBlock_<TValue, Levels<TSpec, TConfig> >::Type   TUltraBlocks_;
-    typedef typename StringSpec<TRankDictionary_>::Type                                 TFibreSpec_;
+    typedef typename DefaultIndexStringSpec<TRankDictionary_>::Type                     TFibreSpec_;
 
     typedef String<TUltraBlocks_, TFibreSpec_>                                          Type;
 };
diff --git a/include/seqan/index/index_fm_rank_dictionary_naive.h b/include/seqan/index/index_fm_rank_dictionary_naive.h
index 1884c2e..dcd9ab0 100644
--- a/include/seqan/index/index_fm_rank_dictionary_naive.h
+++ b/include/seqan/index/index_fm_rank_dictionary_naive.h
@@ -61,7 +61,7 @@ struct Fibre<RankDictionary<TValue, Naive<TSpec, TConfig> >, FibreRanks>
 {
     typedef RankDictionary<TValue, Naive<TSpec, TConfig> >          TRankDictionary_;
     typedef typename Size<TRankDictionary_>::Type                   TSize_;
-    typedef typename StringSpec<TRankDictionary_>::Type TFibreSpec_;
+    typedef typename DefaultIndexStringSpec<TRankDictionary_>::Type TFibreSpec_;
 
     typedef String<TSize_, TFibreSpec_>                             Type;
 };
diff --git a/include/seqan/index/index_fm_rank_dictionary_wt.h b/include/seqan/index/index_fm_rank_dictionary_wt.h
index 1e4d214..79d0232 100644
--- a/include/seqan/index/index_fm_rank_dictionary_wt.h
+++ b/include/seqan/index/index_fm_rank_dictionary_wt.h
@@ -77,6 +77,18 @@ struct WTRDConfig : LevelsRDConfig<TSize, TFibre, LEVELS, WORDS_PER_BLOCK>
 template <typename TSpec = void, typename TConfig = WTRDConfig<> >
 struct WaveletTree {};
 
+template <typename T>
+struct isWaveletTree
+{
+    static constexpr bool Value = false;
+};
+
+template <typename TSpec, typename TConfig>
+struct isWaveletTree<WaveletTree<TSpec, TConfig> >
+{
+    static constexpr bool Value = true;
+};
+
 struct FibreTreeStructure_;
 typedef Tag<FibreTreeStructure_>    const FibreTreeStructure;
 
@@ -346,6 +358,49 @@ getRank(RankDictionary<TValue, WaveletTree<TSpec, TConfig> > const & dict, TPos
     return 0;
 }
 
+template <typename TValue, typename TSpec, typename TConfig, typename TPos, typename TChar>
+inline typename Size<RankDictionary<TValue, WaveletTree<TSpec, TConfig> > >::Type
+_getRankAndValue(RankDictionary<TValue, WaveletTree<TSpec, TConfig> > const & dict, TPos pos, TChar & character)
+{
+    typedef typename Fibre<RankDictionary<TValue, WaveletTree<TSpec, TConfig> >, FibreTreeStructure>::Type const    TWaveletTreeStructure;
+
+    typename Iterator<TWaveletTreeStructure, TopDown<> >::Type iter(dict.waveletTreeStructure, 0);
+
+    bool zero = false;
+    TPos posChar = pos + 1;
+    character = dict.waveletTreeStructure.minCharValue;
+
+    while (true)
+    {
+        TPos rank1 = getRank(dict.ranks[getPosition(iter)], posChar);
+        bool value = getValue(dict.ranks[getPosition(iter)], posChar);
+        TPos addValue = rank1 - value;
+
+        if (value)
+        {
+            character = getCharacter(iter);
+            if (addValue == 0) zero = true;
+            posChar = rank1 - 1;  // -1 because strings start at 0
+            pos = addValue - 1;
+            if (!goRightChild(iter))
+                break;
+        }
+        else
+        {
+            if (addValue > pos) zero = true;
+            posChar -= rank1;
+            pos -= addValue;
+            if (!goLeftChild(iter))
+                break;
+        }
+    }
+
+    if (zero)
+         return 0;
+
+    return pos + 1;
+}
+
 // ----------------------------------------------------------------------------
 // Function _fillStructure()
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/index/index_qgram.h b/include/seqan/index/index_qgram.h
index 90ba86f..7611d23 100644
--- a/include/seqan/index/index_qgram.h
+++ b/include/seqan/index/index_qgram.h
@@ -343,7 +343,7 @@ struct Fibre< Index<TText, TSpec>, FibreCounts> {
     typename Size< TText >::Type,
     typename Size< Index<TText, TSpec> >::Type
     >,
-    typename StringSpec< Index<TText, TSpec> >::Type
+    typename DefaultIndexStringSpec< Index<TText, TSpec> >::Type
     > Type;
 };
 
diff --git a/include/seqan/journaled_string_tree/delta_map.h b/include/seqan/journaled_string_tree/delta_map.h
index c41f986..97cad29 100644
--- a/include/seqan/journaled_string_tree/delta_map.h
+++ b/include/seqan/journaled_string_tree/delta_map.h
@@ -844,7 +844,7 @@ erase(DeltaMap<TConfig, TSpec> & deltaMap,
     for (auto it = itRange.i1; it != itRange.i2; ++it)
     {
         // Find potential right end of this delta.
-        if (!IsSameType<TDeltaType, DeltaTypeIns>::VALUE)
+        SEQAN_IF_CONSTEXPR (!IsSameType<TDeltaType, DeltaTypeIns>::VALUE)
         {
             auto itR = impl::find(deltaMap,
                                   deltaPos + deletionSize(deltaMap._deltaStore, getDeltaRecord(*it).i2, TDeltaType()) - 1,
diff --git a/include/seqan/journaled_string_tree/journaled_string_tree_impl.h b/include/seqan/journaled_string_tree/journaled_string_tree_impl.h
index 1795f3c..7a64acc 100644
--- a/include/seqan/journaled_string_tree/journaled_string_tree_impl.h
+++ b/include/seqan/journaled_string_tree/journaled_string_tree_impl.h
@@ -601,7 +601,7 @@ insert(JournaledStringTree<TSequence, TConfig, TSpec> & jst,
     typedef typename Value<TIds>::Type                      TID;
     typedef typename Size<TJst>::Type                       TSize   SEQAN_TYPEDEF_FOR_DEBUG;
 
-    if (IsSameType<TDeltaType, DeltaTypeIns>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TDeltaType, DeltaTypeIns>::VALUE)
         SEQAN_ASSERT_LEQ(static_cast<TSize>(srcPos), length(impl::member(jst, JstSourceMember())));  // Make sure the delta position does not exceed the source.
     else
         SEQAN_ASSERT_LT(static_cast<TSize>(srcPos), length(impl::member(jst, JstSourceMember())));
diff --git a/include/seqan/journaled_string_tree/journaled_string_tree_traverser_util.h b/include/seqan/journaled_string_tree/journaled_string_tree_traverser_util.h
index ba32ac8..f47c5fd 100644
--- a/include/seqan/journaled_string_tree/journaled_string_tree_traverser_util.h
+++ b/include/seqan/journaled_string_tree/journaled_string_tree_traverser_util.h
@@ -928,7 +928,7 @@ init(TraverserImpl<TJst, JstTraversalSpec<TSpec> > & me,
     TNode* basePtr = &impl::activeNode(me);
 
     SEQAN_ASSERT_GEQ(me._contextSize, 1u);
-    if (IsSameType<Tag<TProxySelector>, SelectFirstProxy>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<Tag<TProxySelector>, SelectFirstProxy>::VALUE)
         impl::moveWindow(me, basePtr, 0, observer, Tag<TProxySelector>());   // We move the traverser to the first position.
     else
         impl::moveWindow(me, basePtr, me._contextSize - 1, observer, Tag<TProxySelector>());
diff --git a/include/seqan/modifier/modifier_padding.h b/include/seqan/modifier/modifier_padding.h
index 83bb805..5fd9e11 100644
--- a/include/seqan/modifier/modifier_padding.h
+++ b/include/seqan/modifier/modifier_padding.h
@@ -80,7 +80,7 @@ template <typename THost>
 struct ModPaddingCargo
 {
     using TSize  = typename Size<THost>::Type;
-    using TValue = typename Value<THost>::Type;
+    using TValue = typename std::remove_const<typename Value<THost>::Type>::type;
 
     TSize   _numPaddedChar  = 0;
     TSize   _remainingSteps = 0;
@@ -165,7 +165,7 @@ struct DefaultIteratorSpec< ModifiedString<THost, ModPadding> >
  * @param [in,out] str  The modified string to be padded.
  * @param [in]     size The number of padded characters.
  * @param [in]     pad  The character to pad the sequence with.
- * 
+ *
  * @datarace Not thread-safe.
  */
 
@@ -211,6 +211,51 @@ length(ModifiedString<THost, ModPadding> const & me)
 }
 
 // ----------------------------------------------------------------------------
+// Function cargoValue()
+// ----------------------------------------------------------------------------
+
+template <typename THost>
+inline typename Reference<ModifiedString<THost, ModPadding> >::Type
+cargoValue(ModifiedString<THost, ModPadding> & me)
+{
+    return cargo(me)._paddedValue;
+}
+
+// NOTE(rrahn): The problem with the padding symbol is, that it is always stored as a member
+// of the modifier class. Hence, if the modifier is const all it's members are const.
+// Now, the cargo could be either defined mutable or, and this what we did right now, the
+// the const is cast-away. However, we use SFINAE to only apply this hack to the Host types,
+// for which this becomes relevant. That are Host types like the Segment class who copy pointer semantics, i.e.
+// the constness of the object is not propagated to the underlying source.
+
+// The default version, where Reference<THost const>::Type gives back a const reference.
+template <typename THost,
+          std::enable_if_t<std::is_same<std::remove_reference_t<
+                                            typename Reference<ModifiedString<THost, ModPadding>>::Type>,
+                                        std::add_const_t<std::remove_reference_t<
+                                            typename Reference<ModifiedString<THost, ModPadding>>::Type>>>::value,
+                           int> = 0>
+inline typename Reference<ModifiedString<THost, ModPadding> >::Type
+cargoValue(ModifiedString<THost, ModPadding> const & me)
+{
+    return cargo(me)._paddedValue;
+}
+
+// The version, where Reference<THost const>::Type gives back a non-const reference.
+template <typename THost,
+          std::enable_if_t<!std::is_same<std::remove_reference_t<
+                                            typename Reference<ModifiedString<THost, ModPadding>>::Type>,
+                                         std::add_const_t<std::remove_reference_t<
+                                            typename Reference<ModifiedString<THost, ModPadding>>::Type>>>::value,
+                           int> = 0>
+inline typename Reference<ModifiedString<THost, ModPadding> >::Type
+cargoValue(ModifiedString<THost, ModPadding> const & me)
+{
+    using TTargetType = typename Reference<ModifiedString<THost, ModPadding> >::Type;
+    return const_cast<TTargetType>(cargo(me)._paddedValue);
+}
+
+// ----------------------------------------------------------------------------
 // Function value()
 // ----------------------------------------------------------------------------
 
@@ -219,7 +264,7 @@ inline typename Reference<ModifiedString<THost, ModPadding> >::Type
 value(ModifiedString<THost, ModPadding> & me, TPosition const pos)
 {
     SEQAN_ASSERT_LT(pos, static_cast<TPosition>(length(me)));
-    return (SEQAN_LIKELY(pos < static_cast<TPosition>(length(host(me))))) ? host(me)[pos] : cargo(me)._paddedValue;
+    return (SEQAN_LIKELY(pos < static_cast<TPosition>(length(host(me))))) ? host(me)[pos] : cargoValue(me);
 }
 
 template <typename THost, typename TPosition>
@@ -227,7 +272,7 @@ inline typename Reference<ModifiedString<THost, ModPadding> const>::Type
 value(ModifiedString<THost, ModPadding> const & me, TPosition const pos)
 {
     SEQAN_ASSERT_LT(pos, static_cast<TPosition>(length(me)));
-    return (SEQAN_LIKELY(pos < static_cast<TPosition>(length(host(me))))) ? value(host(me), pos) : cargo(me)._paddedValue;
+        return (SEQAN_LIKELY(pos < static_cast<TPosition>(length(host(me))))) ? value(host(me), pos) : cargoValue(me);
 }
 
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/parallel.h b/include/seqan/parallel.h
index ac0a3d7..cae1a35 100755
--- a/include/seqan/parallel.h
+++ b/include/seqan/parallel.h
@@ -63,6 +63,8 @@
 #include <future>
 #include <mutex>
 #include <condition_variable>
+#include <unordered_map>
+#include <shared_mutex>
 
 // ============================================================================
 // Module Headers
@@ -89,5 +91,9 @@
 #include <seqan/parallel/parallel_queue_suspendable.h>
 #include <seqan/parallel/parallel_resource_pool.h>
 #include <seqan/parallel/parallel_serializer.h>
+#include <seqan/parallel/enumerable_thread_local.h>
+#include <seqan/parallel/enumerable_thread_local_iterator.h>
+#include <seqan/parallel/parallel_thread_pool.h>
+
 
 #endif  // SEQAN_PARALLEL_H_
diff --git a/include/seqan/parallel/enumerable_thread_local.h b/include/seqan/parallel/enumerable_thread_local.h
new file mode 100644
index 0000000..1bd7a2b
--- /dev/null
+++ b/include/seqan/parallel/enumerable_thread_local.h
@@ -0,0 +1,476 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_ENUMERABLE_THREAD_LOCAL_H_
+#define INCLUDE_SEQAN_ALIGN_PARALLEL_ENUMERABLE_THREAD_LOCAL_H_
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+struct EnumerableThreadLocalIterSpec_;
+using EnumerableThreadLocalIterSpec = Tag<EnumerableThreadLocalIterSpec_>;
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+/*!
+ * @class SimpleThreadLocalManager
+ * @headerfile <seqan/parallel.h>
+ * @brief Internal policy used to manage thread specific storage.
+ * @signature struct SimpleThreadLocalManager;
+ *
+ * Uses a shared mutex to synchronize concurrent access to the storage buffer (multiple read, single write).
+ * This policy checks if the thread-id was already registered and if not creates a new storage instance for the
+ * given thread-id.
+ *
+ * @see CountingThreadLocalManager
+ */
+struct SimpleThreadLocalManager
+{
+    std::shared_timed_mutex  _mutex{};        // TODO(rrahn): Replace by shared_mutex when c++17 is available.
+
+    /*!
+     * @fn SimpleThreadLocalManager::local
+     * @brief Implements the specific <tt>local</tt> policy.
+     * @headerfile <seqan/parallel.h>
+     *
+     * @signature auto local(map, init);
+     * @param map The buffer provided by the @link EnumerableThreadLocal @endlink instance to the hold the thread
+     *            local storage. Must satisfy the <tt>std::map</tt> interface.
+     * @param init The value used to initialize created storage.
+     *
+     * @datarace thread-safe.
+     * @return auto A tuple containing a lvalue reference to the associated storage and a boolean indicating first time
+     * access of the given thread-id.
+     */
+    template <typename TResourceMap, typename TValue>
+    inline auto &
+    local(TResourceMap & map, TValue const & initValue, bool & exists)
+    {
+        decltype(map.find(std::this_thread::get_id())) elemIt;
+
+        { // try to read
+            std::shared_lock<decltype(_mutex)> read_lck(_mutex);
+            elemIt = map.find(std::this_thread::get_id());
+            exists = elemIt != map.end();
+        }
+
+        if (!exists)
+        {
+            {  // Create new entry.
+                std::unique_lock<decltype(_mutex)> write_lck(_mutex);
+                std::tie(elemIt, exists) = map.emplace(std::this_thread::get_id(), initValue);
+            }
+
+            SEQAN_ASSERT(exists);
+            exists = false;  // Notify that element was added for the first time.
+        }
+        return elemIt->second;
+    }
+};
+
+/*!
+ * @class CountingThreadLocalManager
+ * @headerfile <seqan/parallel.h>
+ * @brief Internal policy used to manage thread specific storage for a limited number of threads.
+ * @signature struct SimpleThreadLocalManager;
+ *
+ * Uses a shared mutex to synchronize concurrent access to the storage buffer (multiple read, single write).
+ * This policy checks if the thread-id was already registered and if not creates a new storage instance for the
+ * given thread-id.
+ * In addition maintains an atomic counter to only check for existing values as long as the counter is not 0.
+ * This can be used if the number of threads registering at the @link EnumerableThreadLocal @endlink instance,
+ * is known beforehand. In this case, as soon as all threads have been registered and obtained their local storage,
+ * no further synchronization is necessary.
+ *
+ * @see SimpleThreadLocalManager
+ */
+struct CountingThreadLocalManager
+{
+    std::atomic<size_t>      _count{0};
+    std::shared_timed_mutex  _mutex{};        // TODO(rrahn): Replace by shared_mutex when c++17 is available.
+
+    /*!
+     * @fn CountingThreadLocalManager::local
+     * @brief Implements the specific <tt>local</tt> policy.
+     * @headerfile <seqan/parallel.h>
+     *
+     * @signature auto local(map, init);
+     * @param map The buffer provided by the @link EnumerableThreadLocal @endlink instance to the hold the thread
+     *            local storage. Must satisfy the <tt>std::map</tt> interface.
+     * @param init The value used to initialize created storage.
+     *
+     * @datarace thread-safe.
+     * @return auto A tuple containing a lvalue reference to the associated storage and a boolean indicating first time
+     * access of the given thread-id.
+     */
+    template <typename TResourceMap, typename TValue>
+    inline auto &
+    local(TResourceMap & map, TValue const & initValue, bool & exists)
+    {
+        if (_count.load(std::memory_order_relaxed) == 0)
+            return map.find(std::this_thread::get_id())->second;
+
+        decltype(map.find(std::this_thread::get_id())) elemIt;
+
+        { // try to read
+            std::shared_lock<decltype(_mutex)> read_lck(_mutex);
+            elemIt = map.find(std::this_thread::get_id());
+            exists = elemIt != map.end();
+        }
+
+        if (!exists)
+        {
+            {  // Create new entry.
+                std::unique_lock<decltype(_mutex)> write_lck(_mutex);
+                std::tie(elemIt, exists) = map.emplace(std::this_thread::get_id(), initValue);
+            }
+
+            --_count;
+            SEQAN_ASSERT(exists);
+            exists = false;  // Notify that element was added for the first time.
+        }
+        return elemIt->second;
+    }
+};
+
+// ----------------------------------------------------------------------------
+//  Function setCount()
+// ----------------------------------------------------------------------------
+
+inline void
+setCount(CountingThreadLocalManager & mngr, size_t const count)
+{
+    mngr._count.store(count, std::memory_order_relaxed);
+}
+
+/*!
+ * @class EnumerableThreadLocal
+ * @headerfile <seqan/parallel.h>
+ * @brief Manages thread local storage.
+ * @signature template <typename TValue, typename TManager, typename TSpec>
+ *            class ThreadPool;
+ * @tparam TValue The type of the stored value.
+ * @tparam TManager A policy used to manage the thread local storage. Defaults to @link SimpleThreadLocalManager @endlink.
+ * @tparam TSpec Specialization of the <tt>EnumerableThreadLocal</tt> class. Defaults to <tt>void</tt>.
+ *
+ * The enumerable thread local class can be used to manage thread local storage using a map as
+ * internal buffer. The class offers an iterator interface, such that the thread specific values can be
+ * enumerated allowing to apply reduce operations at the end of the parallel execution.
+ * Creating thread local storage happens via a lazy evaluation using the <tt>local</tt> function.
+ * If a thread, identified by its <a href="http://en.cppreference.com/w/cpp/thread/get_id">thread id</a>,
+ * requests storage for the first time a new thread specific storage will be created and a lvalue reference pointing
+ * to this storage is returned.
+ * If the thread id was already registered, then a lvalue reference to the associated storage will be returned.
+ * The access to the <tt>local</tt> function is thread safe and can be called concurrently.
+ *
+ * A thread local manager can be selected via template argument. This manager ensures safe access from concurrent
+ * invocations. The manager can further be replaced to change the behavior of storing the thread local data.
+ *
+ * @see SimpleThreadLocalManager
+ * @see CountingThreadLocalManager
+ */
+template <typename TValue, typename TManager = SimpleThreadLocalManager, typename TSpec = void>
+class EnumerableThreadLocal
+{
+public:
+
+    //-------------------------------------------------------------------------
+    // Member types.
+
+    using TMap           = std::unordered_map<std::thread::id, TValue>;
+    using TIterator      = Iter<EnumerableThreadLocal, EnumerableThreadLocalIterSpec>;
+    using TConstIterator = Iter<EnumerableThreadLocal const, EnumerableThreadLocalIterSpec>;
+
+    //-------------------------------------------------------------------------
+    // Private Members.
+
+    TMap                     _map{};
+    TValue                   _initValue{};
+    TManager                 _manager{};
+
+    //-------------------------------------------------------------------------
+    // Constructor.
+
+    /*!
+     * @fn EnumerableThreadLocal::EnumerableThreadLocal
+     * @brief Constructing an instance of this class.
+     * @signature EnumerableThreadLocal::EnumerableThreadLocal() = default;
+     * @signature EnumerableThreadLocal::EnumerableThreadLocal(TValue init);
+     *
+     * @param[in] init An optional value used to initialize the newly created storage.
+     * @note The class is not @link CopyConstructibleConcept copy constructible @endlink and not
+     * <a href="http://en.cppreference.com/w/cpp/concept/MoveConstructible">move constructible</a>.
+     */
+    EnumerableThreadLocal() = default;
+
+    explicit EnumerableThreadLocal(TValue initValue) : _initValue(std::move(initValue))
+    {}
+
+    EnumerableThreadLocal(EnumerableThreadLocal const &) = delete;
+    EnumerableThreadLocal(EnumerableThreadLocal &&) = delete;
+
+    //-------------------------------------------------------------------------
+    // Member Functions.
+
+    EnumerableThreadLocal & operator=(EnumerableThreadLocal const &) = delete;
+    EnumerableThreadLocal & operator=(EnumerableThreadLocal &&) = delete;
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+/*!
+ * @mfn EnumerableThreadLocal#Iterator
+ * @brief Constructing an instance of this class.
+ * @headerfile <seqan/parallel.h>
+ * @signature Iterator<TEnumerableThreadLocal>::Type;
+ * @tparam  TEnumerableThreadLocal The type of the enumerable thread local class.
+ * @return Type The type of the iterator.
+ */
+template <typename TValue, typename TManager, typename TSpec,
+          typename TIterTag>
+struct Iterator<EnumerableThreadLocal<TValue, TManager, TSpec>, TIterTag>
+{
+    using Type = typename EnumerableThreadLocal<TValue, TManager, TSpec>::TIterator;
+};
+
+template <typename TValue, typename TManager, typename TSpec,
+          typename TIterTag>
+struct Iterator<EnumerableThreadLocal<TValue, TManager, TSpec> const, TIterTag>
+{
+    using Type = typename EnumerableThreadLocal<TValue, TManager, TSpec>::TConstIterator;
+};
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+//  Function storageManager()
+// ----------------------------------------------------------------------------
+
+/*!
+ * @fn EnumerableThreadLocal#storageManager
+ * @brief Constructing an instance of this class.
+ * @headerfile <seqan/parallel.h>
+ * @signature TManager & storageManager(etl);
+ * @param[in] etl An instance of @link EnumerableThreadLocal @endlink.
+ * @return TManager& A lvalue reference to the associated storage manager.
+ * @datarace not thread-safe.
+ */
+template <typename TValue, typename TManager, typename TSpec>
+inline TManager &
+storageManager(EnumerableThreadLocal<TValue, TManager, TSpec> & me)
+{
+    return me._manager;
+}
+
+template <typename TValue, typename TManager, typename TSpec>
+inline TManager const &
+storageManager(EnumerableThreadLocal<TValue, TManager, TSpec> const & me)
+{
+    return me._manager;
+}
+
+// ----------------------------------------------------------------------------
+//  Function local()
+// ----------------------------------------------------------------------------
+
+/*!
+ * @fn EnumerableThreadLocal#local
+ * @brief Constructing an instance of this class.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature auto & local(etl);
+ * @signature auto & local(etl, b);
+ * @param[in,out] etl An instance of @link EnumerableThreadLocal @endlink.
+ * @param[in,out] b A boolean to indicate successful creation.
+ *
+ * @return auto& A lvalue reference to the associated thread specific storage.
+ * @datarace thread-safe. Concurrent invocations of this function are synchronized via the storage manager.
+ *
+ * Calls the internal <tt>local</tt> member function of the associated storage manager. If the thread-id was used
+ * for the first time <tt>b</tt> will be set to <tt>true</tt> to indicate successful creation of the storage.
+ * If the storage was already created for the given thread-id, then <tt>b</tt> is set to <tt>false</tt>.
+ */
+template <typename TValue, typename TManager, typename TSpec>
+inline auto&
+local(EnumerableThreadLocal<TValue, TManager, TSpec> & me,
+      bool & exists)
+{
+    return  me._manager.local(me._map, me._initValue, exists);
+}
+
+template <typename TValue, typename TManager, typename TSpec>
+inline auto&
+local(EnumerableThreadLocal<TValue, TManager, TSpec> & me)
+{
+    bool exists{true};
+    return local(me, exists); // Double indirection to to iterator and pointer to therad_local storage.
+}
+
+// ----------------------------------------------------------------------------
+// Function begin()
+// ----------------------------------------------------------------------------
+
+/*!
+ * @fn EnumerableThreadLocal#begin
+ * @brief Returns a bidirectional iterator to the thread specific storage.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature TIteator begin(etl, tag);
+ * @param[in] etl An instance of @link EnumerableThreadLocal @endlink.
+ * @param[in] tag A tag to choose the type of the iterator. One of @link ContainerIteratorTags @endlink.
+ *
+ * @return TIteator Iterator to the begin of the thread stores.
+ * @datarace thread-safe.
+ */
+template <typename TValue, typename TManager, typename TSpec,
+          typename TIterSpec>
+inline auto
+begin(EnumerableThreadLocal<TValue, TManager, TSpec> & me,
+      Tag<TIterSpec> const & /*tag*/)
+{
+    return typename EnumerableThreadLocal<TValue, TManager, TSpec>::TIterator{me};
+}
+
+template <typename TValue, typename TManager, typename TSpec,
+          typename TIterSpec>
+inline auto
+begin(EnumerableThreadLocal<TValue, TManager, TSpec> const & me,
+      Tag<TIterSpec> const & /*tag*/)
+{
+    return typename EnumerableThreadLocal<TValue, TManager, TSpec>::TConstIterator{me};
+}
+
+// ----------------------------------------------------------------------------
+// Function end()
+// ----------------------------------------------------------------------------
+
+/*!
+ * @fn EnumerableThreadLocal#end
+ * @brief Returns a bidirectional iterator to the thread specific storage.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature TIteator end(etl, tag);
+ * @param[in] etl An instance of @link EnumerableThreadLocal @endlink.
+ * @param[in] tag A tag to choose the type of the iterator. One of @link ContainerIteratorTags @endlink.
+ *
+ * @return TIteator Iterator to the end of the thread stores.
+ * @datarace thread-safe.
+ */
+template <typename TValue, typename TManager, typename TSpec,
+          typename TIterSpec>
+inline auto
+end(EnumerableThreadLocal<TValue, TManager, TSpec> & me,
+    Tag<TIterSpec> const & /*tag*/)
+{
+    return typename EnumerableThreadLocal<TValue, TManager, TSpec>::TIterator{me._map.end()};
+}
+
+template <typename TValue, typename TManager, typename TSpec,
+          typename TIterSpec>
+inline auto
+end(EnumerableThreadLocal<TValue, TManager, TSpec> const & me,
+    Tag<TIterSpec> const & /*tag*/)
+{
+    return typename EnumerableThreadLocal<TValue, TManager, TSpec>::TConstIterator{me._map.cend()};
+}
+
+// ----------------------------------------------------------------------------
+// Function combine()
+// ----------------------------------------------------------------------------
+
+/*!
+ * @fn EnumerableThreadLocal#combineEach
+ * @brief Enumerates thread local stores and applies an unary functor for each store.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature void combineEach(etl, f);
+ * @param[in] etl An instance of @link EnumerableThreadLocal @endlink.
+ * @param[in] f An unary functor called on each thread local storage.
+ *
+ * @datarace not thread-safe.
+ * @see EnumerableThreadLocal#combine
+ *  @section Possible implementation:
+ * @code{.cpp}
+ * std::for_each(begin(etl), end(etl), f);
+ * @endcode
+ */
+template <typename TValue, typename TManager, typename TSpec,
+          typename TUnaryCombine>
+inline void
+combineEach(EnumerableThreadLocal<TValue, TManager, TSpec> & me,
+            TUnaryCombine && fUnaryCombine)
+{
+    std::shared_lock<decltype(storageManager(me)._mutex)> read_lck(storageManager(me)._mutex);
+    std::for_each(begin(me), end(me), std::forward<TUnaryCombine>(fUnaryCombine));
+}
+
+/*!
+ * @fn EnumerableThreadLocal#combine
+ * @brief Enumerates thread local stores and applies a binary functor for each store.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature void combine(etl, f);
+ * @param[in] etl An instance of @link EnumerableThreadLocal @endlink.
+ * @param[in] f A binary combinator called on each thread local storage.
+ *
+ * @datarace not thread-safe.
+ * @see EnumerableThreadLocal#combineEach
+ * @section Possible implementation:
+ * @code{.cpp}
+ * std::accumulate(begin(etl), end(etl), TValue{}, f);
+ * @endcode
+ */
+template <typename TValue, typename TManager, typename TSpec,
+          typename TBinaryCombine>
+inline auto
+combine(EnumerableThreadLocal<TValue, TManager, TSpec> & me,
+        TBinaryCombine && fBinaryCombine)
+{
+    std::shared_lock<decltype(storageManager(me)._mutex)> read_lck(storageManager(me)._mutex);
+    return std::accumulate(begin(me), end(me), TValue{}, std::forward<TBinaryCombine>(fBinaryCombine));
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLUDE_SEQAN_ALIGN_PARALLEL_ENUMERABLE_THREAD_LOCAL_H_
diff --git a/include/seqan/parallel/enumerable_thread_local_iterator.h b/include/seqan/parallel/enumerable_thread_local_iterator.h
new file mode 100644
index 0000000..033fc1f
--- /dev/null
+++ b/include/seqan/parallel/enumerable_thread_local_iterator.h
@@ -0,0 +1,186 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLDUE_SEQAN_ALIGN_PARALLEL_ENUMERABLE_THREAD_LOCAL_ITERATOR_H_
+#define INCLDUE_SEQAN_ALIGN_PARALLEL_ENUMERABLE_THREAD_LOCAL_ITERATOR_H_
+
+namespace std
+{
+
+template<typename TContainer>
+struct iterator_traits<seqan::Iter<TContainer, seqan::EnumerableThreadLocalIterSpec> > // nolint
+{
+    typedef seqan::Iter<TContainer, seqan::EnumerableThreadLocalIterSpec> TIter; // nolint
+
+    typedef forward_iterator_tag iterator_category; // nolint
+    typedef typename seqan::Value<TIter>::Type value_type; // nolint
+    typedef typename seqan::Difference<TIter>::Type difference_type; // nolint
+    typedef typename seqan::Value<TIter>::Type * pointer; // nolint
+    typedef typename seqan::Reference<TIter>::Type reference; // nolint
+};
+
+}
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+template <typename TEnumerableThreadLocal>
+class Iter<TEnumerableThreadLocal, EnumerableThreadLocalIterSpec>
+{
+public:
+
+    //-------------------------------------------------------------------------
+    // Member Types.
+
+    using TMap = typename TEnumerableThreadLocal::TMap;
+    using TMapIterator = typename IfC<std::is_const<TEnumerableThreadLocal>::value,
+                                      typename TMap::const_iterator,
+                                      typename TMap::iterator>::Type;
+
+    //-------------------------------------------------------------------------
+    // Member Variables.
+
+    TMapIterator _mInnerIter{};
+
+    //-------------------------------------------------------------------------
+    // Constructors.
+
+    Iter() = default;
+
+    Iter(typename TMap::iterator const & it) : _mInnerIter(it)
+    {}
+
+    Iter(typename TMap::const_iterator const & cit) : _mInnerIter(cit)
+    {}
+
+    Iter(TEnumerableThreadLocal & iterable) : Iter(iterable._map.begin())
+    {}
+
+    //-------------------------------------------------------------------------
+    // Member Functions.
+
+    inline auto *
+    operator->()
+    {
+        return &*(*this);
+    }
+
+    inline auto *
+    operator->() const
+    {
+        return &*(*this);
+    }
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+template <typename TEnumerableThreadLocal>
+inline auto &
+operator*(Iter<TEnumerableThreadLocal, EnumerableThreadLocalIterSpec> & me)
+{
+    return me._mInnerIter->second;
+}
+
+template <typename TEnumerableThreadLocal>
+inline auto const &
+operator*(Iter<TEnumerableThreadLocal, EnumerableThreadLocalIterSpec> const & me)
+{
+    return me._mInnerIter->second;
+}
+
+template <typename TEnumerableThreadLocal>
+inline void
+operator++(Iter<TEnumerableThreadLocal, EnumerableThreadLocalIterSpec> & me)
+{
+    ++me._mInnerIter;
+}
+
+template <typename TEnumerableThreadLocal>
+inline void
+operator++(Iter<TEnumerableThreadLocal, EnumerableThreadLocalIterSpec> & me, int /*postfix*/)
+{
+    me._mInnerIter++;
+}
+
+template <typename TEnumerableThreadLocal>
+inline void
+operator--(Iter<TEnumerableThreadLocal, EnumerableThreadLocalIterSpec> & me)
+{
+    --me._mInnerIter;
+}
+
+template <typename TEnumerableThreadLocal>
+inline void
+operator--(Iter<TEnumerableThreadLocal, EnumerableThreadLocalIterSpec> & me, int /*postfix*/)
+{
+    me._mInnerIter--;
+}
+
+template <typename TEnumerableThreadLocalLeft,
+          typename TEnumerableThreadLocalRight,
+          typename = std::enable_if<std::is_same<typename std::decay<TEnumerableThreadLocalLeft>::type,
+                                                 typename std::decay<TEnumerableThreadLocalRight>::type>::value>>
+inline bool
+operator==(Iter<TEnumerableThreadLocalLeft, EnumerableThreadLocalIterSpec> const & lhs,
+           Iter<TEnumerableThreadLocalRight, EnumerableThreadLocalIterSpec> const & rhs)
+{
+    return lhs._mInnerIter == rhs._mInnerIter;
+}
+
+template <typename TEnumerableThreadLocalLeft,
+          typename TEnumerableThreadLocalRight>
+inline bool
+operator!=(Iter<TEnumerableThreadLocalLeft, EnumerableThreadLocalIterSpec> const & lhs,
+           Iter<TEnumerableThreadLocalRight, EnumerableThreadLocalIterSpec> const & rhs)
+{
+    return !(lhs._mInnerIter == rhs._mInnerIter);
+}
+
+}  // namespace seqan
+
+#endif  // #ifndef INCLDUE_SEQAN_ALIGN_PARALLEL_ENUMERABLE_THREAD_LOCAL_ITERATOR_H_
diff --git a/include/seqan/parallel/parallel_algorithms.h b/include/seqan/parallel/parallel_algorithms.h
index 8944c38..895ef79 100644
--- a/include/seqan/parallel/parallel_algorithms.h
+++ b/include/seqan/parallel/parallel_algorithms.h
@@ -160,7 +160,7 @@ partialSum(TTarget &target, TSource const &source, Tag<TParallelTag> parallelTag
 
     // STEP 1: compute sums of all subintervals (in parallel)
     //
-    SEQAN_OMP_PRAGMA(parallel for)
+    SEQAN_OMP_PRAGMA(parallel for num_threads(length(splitter)))
     for (int job = 0; job < (int)length(splitter) - 1; ++job)
         localSums[job + 1] = sum(infix(source, splitter[job], splitter[job + 1]), Serial());
 
@@ -171,7 +171,7 @@ partialSum(TTarget &target, TSource const &source, Tag<TParallelTag> parallelTag
 
     // STEP 3: compute partial sums of each subinterval starting from offset (in parallel)
     //
-    SEQAN_OMP_PRAGMA(parallel for)
+    SEQAN_OMP_PRAGMA(parallel for num_threads(length(splitter)))
     for (int job = 0; job < (int)length(splitter); ++job)
     {
         TConstIterator it = begin(source, Standard()) + splitter[job];
@@ -233,12 +233,13 @@ inline void iterate(TContainer & c, TFunctor f, Tag<TIterTag> const & iterTag, P
 {
     typedef Tag<TIterTag> const                                     TIterSpec;
     typedef typename Position<TContainer>::Type                     TPos;
+    typedef typename std::make_signed<TPos>::type                   TSignedPos;
     typedef typename Iterator<TContainer, TIterSpec>::Type          TIter;
 
     Splitter<TPos> splitter(0, length(c), Parallel());
 
     SEQAN_OMP_PRAGMA(parallel for firstprivate(f))
-    for (TPos i = 0; i < length(splitter); ++i)
+    for (TSignedPos i = 0; i < static_cast<TSignedPos>(length(splitter)); ++i)
     {
        TIter it = begin(c, iterTag) + splitter[i];
        TIter itEnd = begin(c, iterTag) + splitter[i + 1];
diff --git a/include/seqan/parallel/parallel_queue.h b/include/seqan/parallel/parallel_queue.h
index 8edc5b6..d267fed 100644
--- a/include/seqan/parallel/parallel_queue.h
+++ b/include/seqan/parallel/parallel_queue.h
@@ -93,8 +93,8 @@ public:
 
     TString                 data;
     mutable ReadWriteLock   lock;           char pad1[SEQAN_CACHE_LINE_SIZE - sizeof(ReadWriteLock)];
-    size_t                  readerCount;
-    size_t                  writerCount;
+    std::atomic<size_t>     readerCount;
+    std::atomic<size_t>     writerCount;
 
     TAtomicSize headPos;                    char pad4[SEQAN_CACHE_LINE_SIZE - sizeof(TAtomicSize)];
     TAtomicSize headReadPos;                char pad5[SEQAN_CACHE_LINE_SIZE - sizeof(TAtomicSize)];
@@ -145,6 +145,10 @@ public:
 
     ~ConcurrentQueue()
     {
+        // wait for all pending readers to finish
+        while (readerCount.load(std::memory_order_acquire) != 0)
+        {}
+
         SEQAN_ASSERT_EQ(tailPos, tailWritePos);
         SEQAN_ASSERT_EQ(headPos, headReadPos);
         SEQAN_ASSERT(empty(lock));
@@ -154,10 +158,6 @@ public:
         headPos &= mask;
         tailPos &= mask;
 
-        // wait for all pending readers to finish
-        while (readerCount != 0)
-        {}
-
         typename Iterator<TString, Standard>::Type arrayBegin = begin(data, Standard());
 
         if (headPos <= tailPos)
@@ -235,7 +235,7 @@ template <typename TValue, typename TSpec>
 inline void
 lockReading(ConcurrentQueue<TValue, TSpec> & me)
 {
-    atomicInc(me.readerCount);
+    ++me.readerCount;
 }
 
 /*!
@@ -253,7 +253,7 @@ template <typename TValue, typename TSpec>
 inline void
 unlockReading(ConcurrentQueue<TValue, TSpec> & me)
 {
-    atomicDec(me.readerCount);
+    --me.readerCount;
 }
 
 // ----------------------------------------------------------------------------
@@ -274,7 +274,7 @@ template <typename TValue, typename TSpec>
 inline void
 lockWriting(ConcurrentQueue<TValue, TSpec> & me)
 {
-    atomicInc(me.writerCount);
+    ++me.writerCount;
 }
 
 /*!
@@ -291,7 +291,7 @@ template <typename TValue, typename TSpec>
 inline void
 unlockWriting(ConcurrentQueue<TValue, TSpec> & me)
 {
-    atomicDec(me.writerCount);
+    --me.writerCount;
 }
 
 // ----------------------------------------------------------------------------
@@ -512,7 +512,7 @@ inline void
 waitForWriters(ConcurrentQueue<TValue, TSpec> & me, unsigned writerCount)
 {
     SpinDelay spinDelay;
-    while (me.writerCount < writerCount)
+    while (me.writerCount.load(std::memory_order_relaxed) < writerCount)
     {
         waitFor(spinDelay);
     }
@@ -569,7 +569,7 @@ popFront(TValue & result, ConcurrentQueue<TValue, TSpec> & me, Tag<TParallel> pa
 {
     SpinDelay spinDelay;
 
-    while (me.writerCount != 0)
+    while (me.writerCount.load(std::memory_order_relaxed) != 0)
     {
         if (tryPopFront(result, me, parallelTag))
             return true;
diff --git a/include/seqan/parallel/parallel_queue_suspendable.h b/include/seqan/parallel/parallel_queue_suspendable.h
index db1aa13..eb7acb0 100644
--- a/include/seqan/parallel/parallel_queue_suspendable.h
+++ b/include/seqan/parallel/parallel_queue_suspendable.h
@@ -169,12 +169,12 @@ template <typename TValue, typename TSpec>
 inline void
 unlockReading(ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
 {
-    std::unique_lock<std::mutex> lock(me.cs);
-    if (--me.readerCount == 0u)
     {
-        lock.unlock();
-        me.less.notify_all();
+        std::lock_guard<std::mutex> lock(me.cs);
+        if (--me.readerCount != 0u)
+            return;
     }
+    me.less.notify_all();  // publish the condition that reader count is 0.
 }
 
 template <typename TValue, typename TSpec>
@@ -186,12 +186,12 @@ template <typename TValue, typename TSpec>
 inline void
 unlockWriting(ConcurrentQueue<TValue, Suspendable<TSpec> > & me)
 {
-    std::unique_lock<std::mutex> lk(me.cs);
-    if (--me.writerCount == 0u)
     {
-        lk.unlock();
-        me.more.notify_all();
+        std::lock_guard<std::mutex> lk(me.cs);
+        if (--me.writerCount != 0u)
+            return;
     }
+    me.more.notify_all();  // publish the condition, that writer count is 0.
 }
 
 template <typename TValue, typename TSize, typename TSpec>
diff --git a/include/seqan/parallel/parallel_tags.h b/include/seqan/parallel/parallel_tags.h
index 20d395c..dd4ebd3 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/include/seqan/parallel/parallel_tags.h
@@ -30,6 +30,7 @@
 //
 // ==========================================================================
 // Author: David Weese <david.weese at fu-berlin.de>
+//         Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 // Tags to select serial/parallel algorithms.
 // ==========================================================================
@@ -62,16 +63,150 @@ namespace seqan {
  * @tag ParallelismTags#Serial
  * @headerfile <seqan/parallel.h>
  * @brief Tag to select the serial implementation of an algorithm.
+ *
+ * @tag ParallelismTags#Vectorial
+ * @headerfile <seqan/parallel.h>
+ * @brief Tag to select the vectorized implementation of an algorithm.
  */
 
 struct Parallel_;
 typedef Tag<Parallel_> Parallel;
 
+// ----------------------------------------------------------------------------
+// Tag Vectorial
+// ----------------------------------------------------------------------------
+
+struct Vectorial_;
+using Vectorial = Tag<Vectorial_>;
+
+// ----------------------------------------------------------------------------
+// Class ExecutionPolicy
+// ----------------------------------------------------------------------------
+
+/*!
+ * @class ExecutionPolicy
+ * @headerfile <seqan/parallel.h>
+ * @brief Policy to select runtime execution mode for algorithms.
+ * @signature template<typename TThreadingMode, typename TVectorizationMode>
+ *            struct ExecutionPolicy;
+ * @tparam TThreadingMode Type specifying the threading model.
+ *         Can be @link ParallelismTags#Parallel @endlink or @link ParallelismTags#Serial @endlink (default).
+ * @tparam TVectorizationMode Type specifying the vectorization model.
+ *         Can be @link ParallelismTags#Vectorial @endlink or @link ParallelismTags#Serial @endlink (default).
+ *
+ * The <tt>ExecutionPolicy</tt> class is used to select different execution models for certain algorithms.
+ * Depending on the specialization of the template parameters 4 different modes are possible: sequential, parallel,
+ * vectorized and parallel+vectorized. The number of threads for the parallel execution modes can be configured via a
+ * member variable.
+ */
+// Dynamic execution policy.
+template <typename TThreadModel = Serial, typename TVectorSpec = Serial>
+struct ExecutionPolicy
+{
+    // Member variables.
+    /*!
+     * @var size_t ExecutionPolicy::numThreads
+     * @brief The number of threads to use for the parallel execution. Defaults to 1.
+     */
+    size_t _numThreads = 1;
+};
+
+// ----------------------------------------------------------------------------
+// Tag ExecutionPolicy  [Sequential]
+// ----------------------------------------------------------------------------
+
+/*!
+ * @typedef Sequential
+ * @brief A typedef for the sequential @link ExecutionPolicy @endlink version.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature using Sequential = ExecutionPolicy<Serial, Serial>;
+ */
+using Sequential = ExecutionPolicy<>;
+
 // ============================================================================
 // Metafunctions
 // ============================================================================
 
 // ----------------------------------------------------------------------------
+// Metafunction IsVectorized
+// ----------------------------------------------------------------------------
+
+/*!
+ * @mfn ExecutionPolicy#IsVectorized
+ * @brief Evaluates to @link LogicalValuesTags#True @endlink if the execution policy is
+ *        specialized with @link ParallelismTags#Vectorial @endlink.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature IsVectorized<TExecPolicy>::VALUE
+ * @tparam TTExecPolicy The @link ExecutionPolicy @endlink to check.
+ * @return bool <tt>true</tt> if @link ExecutionPolicy @endlink is @link ParallelismTags#Vectorial @endlink,
+ *              otherwise <tt>false</tt>.
+ */
+template <typename T>
+struct IsVectorized : False
+{};
+
+template <>
+struct IsVectorized<Vectorial> : True
+{};
+
+template <typename TPar, typename TVec>
+struct IsVectorized<ExecutionPolicy<TPar, TVec> > :
+    public IsVectorized<TVec>
+{};
+
+// ----------------------------------------------------------------------------
+// Metafunction IsParallel
+// ----------------------------------------------------------------------------
+
+/*!
+ * @mfn ExecutionPolicy#IsParallel
+ * @brief Evaluates to @link LogicalValuesTags#True @endlink if the execution policy is
+ *        specialized with @link ParallelismTags#Parallel @endlink.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature IsParallel<TExecPolicy>::VALUE
+ * @tparam TTExecPolicy The @link ExecutionPolicy @endlink to check.
+ * @return bool <tt>true</tt> if @link ExecutionPolicy @endlink is @link ParallelismTags#Parallel @endlink,
+ *              otherwise <tt>false</tt>.
+ */
+template <typename T>
+struct IsParallel : False
+{};
+
+template <>
+struct IsParallel<Parallel> : True
+{};
+
+template <typename TPar, typename TVec>
+struct IsParallel<ExecutionPolicy<TPar, TVec> > :
+    public IsParallel<TPar>
+{};
+
+// ----------------------------------------------------------------------------
+// Metafunction IsExecutionPolicy
+// ----------------------------------------------------------------------------
+
+/*!
+ * @mfn ExecutionPolicy#IsExecutionPolicy
+ * @brief Checks if a given type is an @link ExecutionPolicy @endlink.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature IsExecutionPolicy<T>::VALUE
+ * @tparam T The type to check.
+ * @return bool <tt>true</tt> if the <tt>T</tt> is an @link ExecutionPolicy @endlink type,
+ *              otherwise <tt>false</tt>.
+ */
+template <typename T>
+struct IsExecutionPolicy : False
+{};
+
+template <typename TPar, typename TVec>
+struct IsExecutionPolicy<ExecutionPolicy<TPar, TVec> > : True
+{};
+
+// ----------------------------------------------------------------------------
 // Metafunction DefaultParallelSpec
 // ----------------------------------------------------------------------------
 
@@ -81,6 +216,43 @@ struct DefaultParallelSpec
     typedef Parallel Type;
 };
 
+// ============================================================================
+// Functions
+// ============================================================================
+
+/*!
+ * @fn ExecutionPolicy#numThreads
+ * @brief Getter function for the thread number.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature auto numThreads(exec);
+ * @param[in] exec The @link ExecutionPolicy @endlink to get the number of threads for.
+ * @return auto The number of threads.
+ */
+template <typename TParallelSpec, typename TVectorizationSpec>
+inline auto
+numThreads(ExecutionPolicy<TParallelSpec, TVectorizationSpec> const & p)
+{
+    return p._numThreads;
+}
+
+/*!
+ * @fn ExecutionPolicy#setNumThreads
+ * @brief Setter function for the thread number.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature void setNumThreads(exec, n);
+ * @param[in,out] exec The @link ExecutionPolicy @endlink to set the number of threads for.
+ * @param[in] n The number of threads used for the parallel execution.
+ */
+template <typename TParallelSpec, typename TVectorizationSpec>
+inline void
+setNumThreads(ExecutionPolicy<TParallelSpec, TVectorizationSpec> & p,
+              size_t const nt)
+{
+    p._numThreads = nt;
+}
+
 }  // namespace seqan
 
 #endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
diff --git a/include/seqan/parallel/parallel_thread_pool.h b/include/seqan/parallel/parallel_thread_pool.h
new file mode 100644
index 0000000..4377e37
--- /dev/null
+++ b/include/seqan/parallel/parallel_thread_pool.h
@@ -0,0 +1,219 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef INCLUDE_SEQAN_PARALLEL_PARALLEL_THREAD_POOL_H_
+#define INCLUDE_SEQAN_PARALLEL_PARALLEL_THREAD_POOL_H_
+
+#if defined(__linux__)
+#include <sched.h>
+#endif  // defined(__linux__)
+
+namespace seqan
+{
+
+// ============================================================================
+// Forwards
+// ============================================================================
+
+// ============================================================================
+// Tags, Classes, Enums
+// ============================================================================
+
+/*!
+ * @class ThreadPool
+ * @headerfile <seqan/parallel.h>
+ * @brief Handles a pool of concurrent <a href="http://en.cppreference.com/w/cpp/thread/thread">std::threads</a>.
+ * @signature class ThreadPool;
+ *
+ * This is a simple raii-wrapper class to manage a set of <tt>std::threads</tt>.
+ */
+class ThreadPool
+{
+public:
+
+    //-------------------------------------------------------------------------
+    // Constructor.
+
+    /*!
+     * @fn ThreadPool::ThreadPool
+     * @brief The constructor.
+     * @signature ThreadPool::TThreadPool() = default;
+     * @signature ThreadPool::TThreadPool(ThreadPool const &) = delete;
+     * @signature ThreadPool::TThreadPool(ThreadPool &&) = delete;
+     *
+     * Creates a new instance with an empty pool.
+     */
+    ThreadPool() = default;
+    ThreadPool(ThreadPool const &) = delete;
+    ThreadPool(ThreadPool &&) = delete;
+
+    ThreadPool& operator=(ThreadPool const &) = delete;
+    ThreadPool& operator=(ThreadPool &&) = delete;
+
+    /*!
+     * @fn ThreadPool::~ThreadPool
+     * @brief The destructor.
+     * @signature ThreadPool::~ThreadPool()
+     *
+     * Safely destroys the thread pool instance by joining all registered threads.
+     * This is an implicit barrier for the owning thread.
+     *
+     * @warning If threads cannot be joined (e.g. dead lock) the destructor will wait forever.
+     */
+    ~ThreadPool()
+    {
+        for_each(std::begin(_mPool), std::end(_mPool),
+                 [] (auto & t)
+                 {
+                     if (t.joinable())
+                        t.join();
+                 });
+    }
+
+    //-------------------------------------------------------------------------
+    // Private Member Variables.
+
+    std::deque<std::thread> _mPool;
+};
+
+// ============================================================================
+// Metafunctions
+// ============================================================================
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+/*!
+ * @fn ThreadPool#spawn
+ * @brief Spawns a new thread and registers it in the thread pool.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature void spawn(pool, callable, ...args);
+ * @param[in,out] pool The @link ThreadPool @endlink to register the new spawned thread in.
+ * @param[in] callable A callable object (e.g. functor or function) that should be executed by the spawned thread.
+ * @param     args Any number of arguments passed to the callable object.
+ *
+ * Emplaces the thread in the <tt>pool</tt> and associates the thread with the callable by passing the <tt>args</tt>
+ * to the callable instance.
+ *
+ * @datarace This function is not thread safe. Concurrent invocations of this function for the same <tt>pool</tt> might
+ * result in undefined behavior.
+ */
+template <typename TCallable, typename ...TArgs>
+inline void
+spawn(ThreadPool & pool,
+      TCallable callable, TArgs && ...args)
+{
+    pool._mPool.emplace_back(callable, std::forward<TArgs>(args)...);
+}
+
+/*!
+ * @fn ThreadPool#join
+ * @brief Explicit barrier over the pool.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature void join(pool);
+ * @param[in,out] pool The @link ThreadPool @endlink to be joined.
+ *
+ * Allows the user to wait for all registered threads to be finished before the calling thread continues its execution.
+ *
+ * @datarace This function is not thread safe. Concurrent invocations of this function for the same <tt>pool</tt> might
+ * result in undefined behavior.
+ */
+inline void
+join(ThreadPool & me)
+{
+    for_each(std::begin(me._mPool), std::end(me._mPool),
+    [](auto & t)
+    {
+        if (t.joinable())
+            t.join();
+    });
+}
+
+/*!
+ * @fn ThreadPool#setCpuAffinity
+ * @brief Pins the spawned threads in a round-robin fashion.
+ * @headerfile <seqan/parallel.h>
+ *
+ * @signature void setCpuAffinity(pool, cpu, scale);
+ * @param[in,out] pool The @link ThreadPool @endlink to pin the threads for.
+ * @param[in] cpu The number of the first cpu to be pinned.
+ * @param[in] scale A scaling factor to
+ *
+ * Iterates over all threads registered in the pool and pins each of them to a cpu in a round-robin fashion.
+ * Using <tt>cpu</tt> and <tt>scale</tt> the cpu ids for pinning the threads can be configured dynamically.
+ * @section Possible implementation:
+ * @code{.cpp}
+ * cpu * scale % std::thread::hardware_concurrency();
+ * @endcode
+ *
+ * @note This function uses pthread functions on the native thread handle and is only available for linux platforms.
+ *       On all other platforms this function is a no-op.
+ *
+ * @datarace This function is not thread safe. Concurrent invocations of this function for the same <tt>pool</tt> might
+ * result in undefined behavior.
+ */
+#if defined(__linux__)
+inline bool
+setCpuAffinity(ThreadPool & me, size_t firstCpu = 0, size_t const scale = 1)
+{
+    SEQAN_ASSERT_GEQ(scale, static_cast<size_t>(1));
+    bool success{true};
+    for (auto & t : me._mPool)
+    {
+        // Create a cpu_set_t object representing a set of CPUs. Clear it and mark
+        // only CPU i as set.
+        cpu_set_t cpuset;
+        CPU_ZERO(&cpuset);
+        CPU_SET((firstCpu * scale) % std::thread::hardware_concurrency(), &cpuset);
+        int rc = pthread_setaffinity_np(t.native_handle(),
+                                        sizeof(cpu_set_t), &cpuset);
+        success &= (rc == 0);
+        ++firstCpu;
+    }
+    return success;
+}
+#else
+inline bool
+setCpuAffinity(ThreadPool & /*me*/, size_t /*firstCpu = 0*/, size_t const /*scale = 0*/)
+{
+    return false;
+}
+#endif  // defined(__linux__)
+
+}  // namespace seqan
+
+#endif  // INCLUDE_SEQAN_PARALLEL_PARALLEL_THREAD_POOL_H_
diff --git a/include/seqan/pipe/pipe_sampler.h b/include/seqan/pipe/pipe_sampler.h
index 0fefa27..d7534a9 100644
--- a/include/seqan/pipe/pipe_sampler.h
+++ b/include/seqan/pipe/pipe_sampler.h
@@ -618,7 +618,7 @@ namespace seqan
         TLimitsString const &limits = me.limits;
         int64_t seqCountPlusOne = length(me.limits);
 
-        SEQAN_OMP_PRAGMA(parallel for reduction(+:sum))
+        SEQAN_OMP_PRAGMA(parallel for reduction(+:sum) if (seqCountPlusOne > 99))
         for (int64_t i = 1; i < seqCountPlusOne; ++i)
         {
             TSize prev = limits[i - 1];
diff --git a/include/seqan/platform.h b/include/seqan/platform.h
index ab0c7ba..b34ce13 100644
--- a/include/seqan/platform.h
+++ b/include/seqan/platform.h
@@ -85,8 +85,8 @@
  */
 #if defined(__ICC)
 #define COMPILER_LINTEL
-#if __ICC < 1600
-     #warning ICC versions older than 16 are not supported.
+#if __ICC < 1700
+     #warning ICC versions older than 17.0 are not supported.
 #endif
 #endif
 
@@ -98,8 +98,8 @@
  */
 #if defined(__ICL)
 #define COMPILER_WINTEL
-#if __ICL < 1600
-     #warning Intel compiler (windows) versions older than 16 are not supported.
+#if __ICL < 1700
+     #warning Intel compiler (windows) versions older than 17.0 are not supported.
 #endif
 #endif
 
@@ -399,12 +399,17 @@ typedef int8_t __int8;     // nolint
 #define SEQAN_UNLIKELY(x)    (x)
 #endif
 
-// A macro to eliminate warnings on GCC and Clang
+// A macro to eliminate warnings for unused entities.
+#if __cplusplus >= 201703L
+#define SEQAN_UNUSED [[maybe_unused]]
+#else
 #if defined(COMPILER_GCC) || defined(COMPILER_CLANG) || defined(COMPILER_LINTEL)
-#define SEQAN_UNUSED __attribute__((unused))
+#define SEQAN_UNUSED [[gnu::unused]]
 #else
 #define SEQAN_UNUSED
-#endif
+#endif // defined(COMPILER_GCC) || defined(COMPILER_CLANG) || defined(COMPILER_LINTEL)
+#endif // __cplusplus >= 201703L
+
 // backwards compatibility
 #define SEQAN_UNUSED_TYPEDEF SEQAN_UNUSED
 
@@ -477,9 +482,9 @@ typedef int8_t __int8;     // nolint
     #include <endian.h>
 #endif // __GLIBC__
 
-#if defined(__FreeBSD__) || (defined(__has_include) && __has_include(<sys/endian.h>))
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
     #include <sys/endian.h>
-#endif // defined(__FreeBSD__)
+#endif // defined *BSD
 
 #ifndef SEQAN_BIG_ENDIAN
     #if (defined( _BYTE_ORDER  ) && ( _BYTE_ORDER   ==        _BIG_ENDIAN  )) || \
@@ -546,4 +551,11 @@ inline void enforceLittleEndian(double & in)
     #define SEQAN_DEFAULT_PAGESIZE 64 * 1024
 #endif
 
+// IF_CONSTEXPR
+#if __cplusplus >= 201703L
+#define SEQAN_IF_CONSTEXPR if constexpr
+#else
+#define SEQAN_IF_CONSTEXPR if
+#endif
+
 #endif // HEADER GUARD
diff --git a/include/seqan/score/score_matrix.h b/include/seqan/score/score_matrix.h
index a2e7c89..0d6d1e1 100644
--- a/include/seqan/score/score_matrix.h
+++ b/include/seqan/score/score_matrix.h
@@ -123,6 +123,14 @@ public:
         : data_gap_extend(_gap_extend), data_gap_open(_gap_open) {
         loadScoreMatrix(*this, filename);
     }
+
+    Score(Score const &) = default;
+    Score(Score &&) = default;
+
+    Score & operator=(Score const &) = default;
+    Score & operator=(Score &&) = default;
+
+    ~Score() = default;
 };
 
 
diff --git a/include/seqan/score/score_matrix_data.h b/include/seqan/score/score_matrix_data.h
index b7dcd96..93ea4c8 100644
--- a/include/seqan/score/score_matrix_data.h
+++ b/include/seqan/score/score_matrix_data.h
@@ -119,14 +119,14 @@ typedef Blosum30_ ScoreSpecBlosum30;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecBlosum30> > Blosum30;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecBlosum30> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecBlosum30> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         // The matrix data, ordered by letter.
         // Matrix made by matblas from blosum30.iij
         // * column uses minimum score
@@ -134,7 +134,7 @@ struct ScoringMatrixData_<int, AminoAcid, ScoreSpecBlosum30> {
         // Blocks Database = /data/blocks_5.0/blocks.dat
         // Cluster Percentage: >= 30
         // Entropy =   0.1424, Expected =  -0.1074
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              4,  0, -3,  0,  0, -2,  0, -2,  0, -1,  0, -1,  1,  0,  0, -1,  1, -1,  1,  1,  0,  1, -5, -4,  0,  0, -7,
              0,  5, -2,  5,  0, -3,  0, -2, -2, -2,  0, -1, -2,  4, -1, -2, -1, -2,  0,  0, -1, -2, -5, -3,  0, -1, -7,
             -3, -2, 17, -3,  1, -3, -4, -5, -2, -1, -3,  0, -2, -1, -2, -3, -2, -2, -2, -2, -2, -2, -2, -6,  0, -2, -7,
@@ -214,21 +214,21 @@ typedef Blosum45_ ScoreSpecBlosum45;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecBlosum45> > Blosum45;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecBlosum45> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecBlosum45> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         // Matrix made by matblas from blosum45.iij
         // * column uses minimum score
         // BLOSUM Clustered Scoring Matrix in 1/3 Bit Units
         // Blocks Database = /data/blocks_5.0/blocks.dat
         // Cluster Percentage: >= 45
         // Entropy =   0.3795, Expected =  -0.2789
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              5, -1, -1, -2, -1, -2,  0, -2, -1, -1, -1, -1, -1, -1,  0, -1, -1, -2,  1,  0,  0,  0, -2, -2, -1,  0, -5,
             -1,  4, -2,  5,  1, -3, -1,  0, -3, -3,  0, -3, -2,  4, -1, -2,  0, -1,  0,  0, -1, -3, -4, -2,  2, -1, -5,
             -1, -2, 12, -3, -3, -2, -3, -3, -3, -3, -3, -2, -2, -2, -2, -4, -3, -3, -1, -1, -2, -1, -5, -3, -3, -2, -5,
@@ -307,21 +307,21 @@ typedef Blosum62_ ScoreSpecBlosum62;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecBlosum62> > Blosum62;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecBlosum62> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecBlosum62> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         // Matrix made by matblas from blosum62.iij
         // * column uses minimum score
         // BLOSUM Clustered Scoring Matrix in 1/2 Bit Units
         // Blocks Database = /data/blocks_5.0/blocks.dat
         // Cluster Percentage: >= 62
         // Entropy =   0.6979, Expected =  -0.5209
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              4, -2,  0, -2, -1, -2,  0, -2, -1, -1, -1, -1, -1, -2,  0, -1, -1, -1,  1,  0,  0,  0, -3, -2, -1,  0, -4,
             -2,  4, -3,  4,  1, -3, -1,  0, -3, -4,  0, -4, -3,  3, -1, -2,  0, -1,  0, -1, -1, -3, -4, -3,  1, -1, -4,
              0, -3,  9, -3, -4, -2, -3, -3, -1, -1, -3, -1, -1, -3, -2, -3, -3, -3, -1, -1, -2, -1, -2, -2, -3, -2, -4,
@@ -400,21 +400,21 @@ typedef Blosum80_ ScoreSpecBlosum80;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecBlosum80> > Blosum80;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecBlosum80> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecBlosum80> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         // Matrix made by matblas from blosum80_3.iij
         // * column uses minimum score
         // BLOSUM Clustered Scoring Matrix in 1/3 Bit Units
         // Blocks Database = /data/blocks_5.0/blocks.dat
         // Cluster Percentage: >= 80
         // Entropy =   0.9868, Expected =  -0.7442
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              7,  -3,  -1,  -3,  -2,  -4,   0,  -3,  -3,  -3,  -1,  -3,  -2,  -3,  -1,  -1,  -2,  -3,   2,   0,  -1,  -1,  -5,  -4,  -2,  -1,  -8,
             -3,   6,  -6,   6,   1,  -6,  -2,  -1,  -6,  -7,  -1,  -7,  -5,   5,  -3,  -4,  -1,  -2,   0,  -1,  -3,  -6,  -8,  -5,   0,  -3,  -8,
             -1,  -6,  13,  -7,  -7,  -4,  -6,  -7,  -2,  -3,  -6,  -3,  -3,  -5,  -4,  -6,  -5,  -6,  -2,  -2,  -4,  -2,  -5,  -5,  -7,  -4,  -8,
@@ -493,14 +493,14 @@ typedef Pam40_ ScoreSpecPam40;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecPam40> > Pam40;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecPam40> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecPam40> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         //
         // This matrix was produced by "pam" Version 1.0.6 [28-Jul-93]
         //
@@ -510,7 +510,7 @@ struct ScoringMatrixData_<int, AminoAcid, ScoreSpecPam40> {
         //
         // Lowest score = -15, Highest score = 13
         //
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              6,  -3,  -6,  -3,  -2,  -7,  -1,  -6,  -4,  -5,  -6,  -5,  -4,  -3,  -3,  -1,  -3,  -6,   0,   0,  -3,  -2, -12,  -7,  -2,  -3, -15,
             -3,   6, -11,   6,   2,  -9,  -2,  -1,  -5,  -7,  -2,  -8,  -8,   6,  -4,  -6,  -2,  -6,  -1,  -2,  -4,  -7,  -9,  -6,   1,  -4, -15,
             -6, -11,   9, -12, -12, -11,  -8,  -7,  -5,  -9, -12, -13, -12,  -9,  -8,  -7, -12,  -7,  -2,  -7,  -8,  -5, -14,  -3, -12,  -8, -15,
@@ -589,14 +589,14 @@ typedef Pam120_ ScoreSpecPam120;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecPam120> > Pam120;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecPam120> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecPam120> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         // This matrix was produced by "pam" Version 1.0.6 [28-Jul-93]
         //
         // PAM 120 substitution matrix, scale = ln(2)/2 = 0.346574
@@ -605,7 +605,7 @@ struct ScoringMatrixData_<int, AminoAcid, ScoreSpecPam120> {
         //
         // Lowest score = -8, Highest score = 12
         //
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              3,  0, -3,  0,  0, -4,  1, -3, -1, -2, -2, -3, -2, -1, -1,  1, -1, -3,  1,  1, -1,  0, -7, -4, -1, -1, -8,
              0,  4, -6,  4,  3, -5,  0,  1, -3, -4,  0, -4, -4,  3, -1, -2,  0, -2,  0,  0, -1, -3, -6, -3,  2, -1, -8,
             -3, -6,  9, -7, -7, -6, -4, -4, -3, -5, -7, -7, -6, -5, -4, -4, -7, -4,  0, -3, -4, -3, -8, -1, -7, -4, -8,
@@ -684,14 +684,14 @@ typedef Pam200_ ScoreSpecPam200;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecPam200> > Pam200;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecPam200> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecPam200> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         // This matrix was produced by "pam" Version 1.0.6 [28-Jul-93]
         //
         // PAM 200 substitution matrix, scale = ln(2)/3 = 0.231049
@@ -700,7 +700,7 @@ struct ScoringMatrixData_<int, AminoAcid, ScoreSpecPam200> {
         //
         // Lowest score = -9, Highest score = 18
         //
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              3,  0, -3,  0,  0, -4,  1, -2, -1, -2, -2, -2, -2,  0,  0,  1, -1, -2,  1,  1,  0,  0, -7, -4,  0,  0, -9,
              0,  3, -5,  4,  3, -6,  0,  1, -3, -4,  0, -4, -3,  3, -1, -1,  1, -1,  1,  0, -1, -3, -6, -4,  2, -1, -9,
             -3, -5, 12, -6, -7, -6, -4, -4, -3, -5, -7, -7, -6, -5, -4, -4, -7, -4,  0, -3, -4, -2, -9,  0, -7, -4, -9,
@@ -779,14 +779,14 @@ typedef Pam250_ ScoreSpecPam250;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecPam250> > Pam250;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecPam250> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecPam250> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         // This matrix was produced by "pam" Version 1.0.6 [28-Jul-93]
         //
         // PAM 250 substitution matrix, scale = ln(2)/3 = 0.231049
@@ -795,7 +795,7 @@ struct ScoringMatrixData_<int, AminoAcid, ScoreSpecPam250> {
         //
         // Lowest score = -8, Highest score = 17
         //
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              2,  0, -2,  0,  0, -3,  1, -1, -1, -2, -1, -2, -1,  0,  0,  1,  0, -2,  1,  1,  0,  0, -6, -3,  0,  0, -8,
              0,  3, -4,  3,  3, -4,  0,  1, -2, -3,  1, -3, -2,  2, -1, -1,  1, -1,  0,  0, -1, -2, -5, -3,  2, -1, -8,
             -2, -4, 12, -5, -5, -4, -3, -3, -2, -4, -5, -6, -5, -4, -3, -3, -5, -4,  0, -2, -3, -2, -8,  0, -5, -3, -8,
@@ -874,14 +874,14 @@ typedef Vtml200_ ScoreSpecVtml200;
 typedef Score<int, ScoreMatrix<AminoAcid, ScoreSpecVtml200> > Vtml200;
 
 
-template <>
-struct ScoringMatrixData_<int, AminoAcid, ScoreSpecVtml200> {
+template <typename TValue>
+struct ScoringMatrixData_<TValue, AminoAcid, ScoreSpecVtml200> {
     enum {
         VALUE_SIZE = ValueSize<AminoAcid>::VALUE,
         TAB_SIZE = VALUE_SIZE * VALUE_SIZE
     };
 
-    static inline int const * getData() {
+    static inline TValue const * getData() {
         // VTML200
         //
         // This matrix was produced by scripts written by
@@ -907,7 +907,7 @@ struct ScoringMatrixData_<int, AminoAcid, ScoreSpecVtml200> {
         //
         // The latest version of this perl script can be downloaded at
         // http://www.molgen.mpg.de/~muelle_t
-        static int const _data[TAB_SIZE] = {
+        static TValue const _data[TAB_SIZE] = {
              4, -1,  1, -1, -1, -3,  0, -2, -1, -2, -1, -2, -1, -1, -1,  0, -1, -2,  1,  1, -1,  0, -4, -3, -1, -1, -6,
             -1,  4, -3,  5,  2, -5,  0,  1, -4, -5,  0, -5, -3,  4, -1, -1,  1, -1,  1,  0, -1, -3, -5, -3,  1, -1, -6,
              1, -3, 12, -4, -4, -3, -2, -2,  0, -2, -4, -3, -1, -2, -1, -3, -3, -3,  1,  0, -1,  1, -6,  0, -4, -1, -6,
diff --git a/include/seqan/score/score_matrix_dyn.h b/include/seqan/score/score_matrix_dyn.h
index 8f80070..d43dc64 100644
--- a/include/seqan/score/score_matrix_dyn.h
+++ b/include/seqan/score/score_matrix_dyn.h
@@ -137,7 +137,26 @@ class Score<TValue, ScoreMatrix<AminoAcid, ScoreSpecSelectable> > :
     public Score<TValue, ScoreMatrix<AminoAcid, Default> >
 {
 public:
+
+    using TBaseScore = Score<TValue, ScoreMatrix<AminoAcid, Default>>;
+
     AminoAcidScoreMatrixID _ident = static_cast<AminoAcidScoreMatrixID>(0u);
+
+    explicit Score(TValue _gap_extend = -1) :
+        TBaseScore(_gap_extend)
+    {}
+
+    Score(TValue _gap_extend, TValue _gap_open) :
+        TBaseScore(_gap_extend, _gap_open)
+    {}
+
+    Score(Score const &) = default;
+    Score(Score &&) = default;
+
+    Score & operator=(Score const &) = default;
+    Score & operator=(Score &&) = default;
+
+    ~Score() = default;
 };
 
 using SelectableAminoAcidMatrix =  Score<int, ScoreMatrix<AminoAcid, ScoreSpecSelectable> >;
diff --git a/include/seqan/score/score_simd_wrapper.h b/include/seqan/score/score_simd_wrapper.h
index f964d49..24c935e 100644
--- a/include/seqan/score/score_simd_wrapper.h
+++ b/include/seqan/score/score_simd_wrapper.h
@@ -72,7 +72,13 @@ template <typename TScoreVec, typename TScore>
 class Score<TScoreVec, ScoreSimdWrapper<TScore> >
 {
 public:
+    using TVecValue = typename Value<TScoreVec>::Type;
     using TBaseScoreSpec = typename Spec<TScore>::Type;
+    using TBaseScore = Score<typename IfC<sizeof(TVecValue) <= 2,
+                                          int32_t,
+                                          typename IfC<sizeof(TVecValue) == 8, int64_t, TVecValue>::Type
+                                         >::Type,
+                             TBaseScoreSpec>;
 
     // We can be either a SimpleScore or a ScoreMatrix.
     TScoreVec data_match        = createVector<TScoreVec>(0);
@@ -80,7 +86,7 @@ public:
     TScoreVec data_gap_extend   = createVector<TScoreVec>(-1);
     TScoreVec data_gap_open     = createVector<TScoreVec>(-1);
 
-    TScore const * _baseScorePtr;   // Only needed for the ScoreMatrix data table.
+    TBaseScore _baseScore;   // Only needed for the ScoreMatrix data table.
 
     // Default Constructor.
     Score()
@@ -93,8 +99,7 @@ public:
             data_match(createVector<TScoreVec>(scoreMatch(pScore))),
             data_mismatch(createVector<TScoreVec>(scoreMismatch(pScore))),
             data_gap_extend(createVector<TScoreVec>(scoreGapExtend(pScore))),
-            data_gap_open(createVector<TScoreVec>(scoreGapOpen(pScore))),
-            _baseScorePtr(nullptr)
+            data_gap_open(createVector<TScoreVec>(scoreGapOpen(pScore)))
     {
         ignoreUnusedVariableWarning(dummy);
     }
@@ -104,10 +109,12 @@ public:
           SEQAN_CTOR_ENABLE_IF(And<IsScoreMatrix_<TScoreSpec2>, IsSameType<TScoreSpec2, TBaseScoreSpec> >)) :
             data_gap_extend(createVector<TScoreVec>(scoreGapExtend(pScore))),
             data_gap_open(createVector<TScoreVec>(scoreGapOpen(pScore))),
-            _baseScorePtr(&pScore)
+            _baseScore(pScore)
     {
         ignoreUnusedVariableWarning(dummy);
     }
+
+    //TODO(rrahn): implement the assignment operator.
 };
 
 // ============================================================================
@@ -119,6 +126,24 @@ public:
 // ============================================================================
 
 // ----------------------------------------------------------------------------
+// Function baseScore();
+// ----------------------------------------------------------------------------
+
+template <typename TValue, typename TScore>
+inline auto &
+underlying(Score<TValue, ScoreSimdWrapper<TScore> > & me)
+{
+    return me._baseScore;
+}
+
+template <typename TValue, typename TScore>
+inline auto const &
+underlying(Score<TValue, ScoreSimdWrapper<TScore> > const & me)
+{
+    return me._baseScore;
+}
+
+// ----------------------------------------------------------------------------
 // Function score(); SimpleScore Wrapper
 // ----------------------------------------------------------------------------
 
@@ -141,8 +166,7 @@ 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);
-    return gather(&sc._baseScorePtr->data_tab[0], val1 + val2);
+    return gather(&sc._baseScore.data_tab[0], val1 + val2);
 }
 
 }
diff --git a/include/seqan/seeds/banded_chain_alignment_impl.h b/include/seqan/seeds/banded_chain_alignment_impl.h
index 970d993..d1ca8c9 100644
--- a/include/seqan/seeds/banded_chain_alignment_impl.h
+++ b/include/seqan/seeds/banded_chain_alignment_impl.h
@@ -280,19 +280,19 @@ _horizontalCellInitialization(DPScout_<TDPCell, BandedChainAlignmentScout> const
 
 // Determines the various tracking options for the current dp matrix.
 template <typename TScout, typename TNavigator, typename TColumnDescriptor, typename TCellDescriptor, typename TFreeEndGaps,
-          typename TMatrixSpec, typename TGapCosts, typename TTracebackSpec>
+          typename TMatrixSpec, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy>
 inline void _determineTrackingOptions(unsigned & res,
                                       TScout const & scout,
                                       TNavigator const & traceMatrixNavigator,
                                       TColumnDescriptor const & /*columnDescriptor*/,
                                       TCellDescriptor const & /*cellDescriptor*/,
-                                      DPProfile_<BandedChainAlignment_<TFreeEndGaps, TMatrixSpec>, TGapCosts, TTracebackSpec> const &)
+                                      DPProfile_<BandedChainAlignment_<TFreeEndGaps, TMatrixSpec>, TGapCosts, TTracebackSpec, TExecPolicy> const &)
 {
     if (coordinate(traceMatrixNavigator, +DPMatrixDimension_::HORIZONTAL) >=
         scout._dpScoutStatePtr->_horizontalNextGridOrigin)
     {
         // Matches an initialization row.
-        if (IsSameType<typename TColumnDescriptor::TLocation, PartialColumnBottom>::VALUE)
+        SEQAN_IF_CONSTEXPR (IsSameType<typename TColumnDescriptor::TLocation, PartialColumnBottom>::VALUE)
         {
             // Matches the cells that have to be stored for initializing the next matrix horizontally.
             if (coordinate(traceMatrixNavigator, +DPMatrixDimension_::VERTICAL) + traceMatrixNavigator._laneLeap ==
@@ -316,9 +316,9 @@ inline void _determineTrackingOptions(unsigned & res,
                 res |= BandedChainTracking::OPTION_STORE_INIT_COLUMN;
 
         // We are in the column that has to be tracked, if we are in the last cell.
-        if (IsSameType<TCellDescriptor, LastCell>::VALUE)
+        SEQAN_IF_CONSTEXPR (IsSameType<TCellDescriptor, LastCell>::VALUE)
         {
-            if (IsSameType<TMatrixSpec, BandedChainFinalDPMatrix>::VALUE)
+            SEQAN_IF_CONSTEXPR (IsSameType<TMatrixSpec, BandedChainFinalDPMatrix>::VALUE)
             {
                 if (IsFreeEndGap_<TFreeEndGaps, DPLastRow>::VALUE)
                     res |= BandedChainTracking::OPTION_IS_LAST_ROW;
@@ -331,18 +331,18 @@ inline void _determineTrackingOptions(unsigned & res,
 
         // We track the maximal score if we are in the final column
         // For the full column we need to check if we are beyond the initialization row.
-        if (IsSameType<typename TColumnDescriptor::TLocation, FullColumn>::VALUE)
+        SEQAN_IF_CONSTEXPR (IsSameType<typename TColumnDescriptor::TLocation, FullColumn>::VALUE)
         {
-            if (IsSameType<typename TColumnDescriptor::TColumnProperty, DPFinalColumn>::VALUE)
+            SEQAN_IF_CONSTEXPR (IsSameType<typename TColumnDescriptor::TColumnProperty, DPFinalColumn>::VALUE)
             {
-                if (IsSameType<TCellDescriptor, LastCell>::VALUE)
+                SEQAN_IF_CONSTEXPR (IsSameType<TCellDescriptor, LastCell>::VALUE)
                 {
                     res |= BandedChainTracking::OPTION_IS_LAST_COLUMN | BandedChainTracking::OPTION_IS_LAST_ROW;
                 }
                 else if (coordinate(traceMatrixNavigator, +DPMatrixDimension_::VERTICAL) >=
                          scout._dpScoutStatePtr->_verticalNextGridOrigin)
                 {
-                    if (IsSameType<TMatrixSpec, BandedChainFinalDPMatrix>::VALUE)
+                    SEQAN_IF_CONSTEXPR (IsSameType<TMatrixSpec, BandedChainFinalDPMatrix>::VALUE)
                     {
                         if (IsFreeEndGap_<TFreeEndGaps, DPLastColumn>::VALUE)
                             res |= BandedChainTracking::OPTION_IS_LAST_COLUMN;
@@ -356,15 +356,15 @@ inline void _determineTrackingOptions(unsigned & res,
         }
         else  // Banded version we track all scores - initialization row ends in first cell of final column
         {
-            if (IsSameType<typename TColumnDescriptor::TColumnProperty, DPFinalColumn>::VALUE)
+            SEQAN_IF_CONSTEXPR (IsSameType<typename TColumnDescriptor::TColumnProperty, DPFinalColumn>::VALUE)
             {
-                if (IsSameType<TCellDescriptor, LastCell>::VALUE)
+                SEQAN_IF_CONSTEXPR (IsSameType<TCellDescriptor, LastCell>::VALUE)
                 {
                     res |= BandedChainTracking::OPTION_IS_LAST_COLUMN | BandedChainTracking::OPTION_IS_LAST_ROW;
                 }
                 else
                 {
-                    if (IsSameType<TMatrixSpec, BandedChainFinalDPMatrix>::VALUE)
+                    SEQAN_IF_CONSTEXPR (IsSameType<TMatrixSpec, BandedChainFinalDPMatrix>::VALUE)
                     {
                         if (IsFreeEndGap_<TFreeEndGaps, DPLastColumn>::VALUE)
                             res |= BandedChainTracking::OPTION_IS_LAST_COLUMN;
@@ -407,64 +407,91 @@ _applyBandedChainTracking(TDPScout & scout,
 // ----------------------------------------------------------------------------
 
 // Overload of _computeCell function to add functionality specific to the bande chain alignment.
-template <typename TDPScout, typename TTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
-          typename TSeqHValue, typename TSeqVValue, typename TScoringScheme, typename TColumnDescriptor,
-          typename TCellDescriptor, typename TFreeEndGaps, typename TDPMatrixLocation, typename TTracebackConfig>
+template <typename TDPScout,
+          typename TTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSeqHValue,
+          typename TSeqVValue,
+          typename TScoringScheme,
+          typename TColumnDescriptor,
+          typename TCellDescriptor,
+          typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTracebackConfig, typename TExecPolicy>
 inline void
 _computeCell(TDPScout & scout,
              TTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const & previousDiagonal,
-             DPCell_<TScoreValue, TGapCosts> const & previousHorizontal,
-             DPCell_<TScoreValue, TGapCosts> const & previousVertical,
+             TDPCell & current,
+             TDPCell & diagonal,
+             TDPCell const & horizontal,
+             TDPCell & vertical,
              TSeqHValue const & seqHVal,
              TSeqVValue const & seqVVal,
              TScoringScheme const & scoringScheme,
              TColumnDescriptor const &,
              TCellDescriptor const &,
-             DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > const &)
+             DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig>, TExecPolicy> const &)
 {
-    typedef DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > TDPProfile;
+    typedef DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>,
+                       TGapCosts,
+                       TracebackOn<TTracebackConfig>,
+                       TExecPolicy> TDPProfile;
     typedef DPMetaColumn_<TDPProfile, TColumnDescriptor> TMetaColumnProfile;
 
     assignValue(
         traceMatrixNavigator,
-        _computeScore(activeCell, previousDiagonal, previousHorizontal, previousVertical, seqHVal, seqVVal,
+        _computeScore(current, diagonal, horizontal, vertical, seqHVal, seqVVal,
                       scoringScheme, typename RecursionDirection_<TMetaColumnProfile, TCellDescriptor>::Type(),
                       TDPProfile()));
+
     if (TrackingEnabled_<TMetaColumnProfile, TCellDescriptor>::VALUE)
-        _applyBandedChainTracking(scout, traceMatrixNavigator, activeCell, TColumnDescriptor(), TCellDescriptor(), TDPProfile());
+    {
+        _setVerticalScoreOfCell(current, _verticalScoreOfCell(vertical));
+        _applyBandedChainTracking(scout, traceMatrixNavigator, current, TColumnDescriptor(), TCellDescriptor(),
+                                  TDPProfile());
+    }
 }
 
 // ----------------------------------------------------------------------------
 // Function _computeCell()              [BandedChainAlignment, DPInitialColumn]
 // ----------------------------------------------------------------------------
 
-template <typename TDPScout, typename TDPTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
-          typename TSeqHValue, typename TSeqVValue, typename TScoringScheme, typename TColumnType, typename TCellDescriptor,
-          typename TSpec, typename TDPMatrixLocation, typename TTracebackConfig>
+template <typename TDPScout,
+          typename TDPTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSeqHValue,
+          typename TSeqVValue,
+          typename TScoringScheme,
+          typename TColumnType,
+          typename TCellDescriptor,
+          typename TSpec, typename TDPMatrixLocation, typename TGapCosts, typename TTracebackConfig, typename TExecPolicy>
 inline void
 _computeCell(TDPScout & scout,
              TDPTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
+             TDPCell & current,
+             TDPCell & diagonal,
+             TDPCell const & horizontal,
+             TDPCell & vertical,
              TSeqHValue const &,
              TSeqVValue const &,
              TScoringScheme const & /*scoringScheme*/,
              MetaColumnDescriptor<DPInitialColumn, TColumnType> const & /*metaColumnDescriptor*/,
              TCellDescriptor const & /*cellDescriptor*/,
-             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > const & /*dpProfile*/)
+             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig>, TExecPolicy> const & /*dpProfile*/)
 {
-    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > TDPProfile;
+    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>,
+                       TGapCosts,
+                       TracebackOn<TTracebackConfig>,
+                       TExecPolicy> TDPProfile;
     typedef MetaColumnDescriptor<DPInitialColumn, TColumnType> TColumnDescriptor;
     typedef DPMetaColumn_<TDPProfile, TColumnDescriptor> TMetaColumnProfile;
 
-    activeCell = _verticalCellInitialization(scout, traceMatrixNavigator);
-    assignValue(traceMatrixNavigator, +TraceBitMap_<>::NONE);
+    _scoreOfCell(diagonal) = _scoreOfCell(horizontal);
+    current = _verticalCellInitialization(scout, traceMatrixNavigator);
+    assignValue(traceMatrixNavigator, TraceBitMap_<>::NONE);
+    _scoreOfCell(vertical) = _scoreOfCell(current);
+    _setVerticalScoreOfCell(vertical, _verticalScoreOfCell(current));
     if (TrackingEnabled_<TMetaColumnProfile, TCellDescriptor>::VALUE)
-        _applyBandedChainTracking(scout, traceMatrixNavigator, activeCell, TColumnDescriptor(), TCellDescriptor(), TDPProfile());
+        _applyBandedChainTracking(scout, traceMatrixNavigator, current, TColumnDescriptor(), TCellDescriptor(),
+                                  TDPProfile());
 }
 
 // ----------------------------------------------------------------------------
@@ -484,7 +511,7 @@ _computeHorizontalInitCell(TDPScout & scout,
     typedef DPMetaColumn_<TDPProfile, TColumnDescriptor> TMetaColumnProfile;
 
     activeCell = _horizontalCellInitialization(scout, traceMatrixNavigator);
-    assignValue(traceMatrixNavigator, +TraceBitMap_<>::NONE);
+    assignValue(traceMatrixNavigator, TraceBitMap_<>::NONE);
     if (TrackingEnabled_<TMetaColumnProfile, TCellDescriptor>::VALUE)
         _applyBandedChainTracking(scout, traceMatrixNavigator, activeCell, TColumnDescriptor(), TCellDescriptor(), TDPProfile());
 }
@@ -494,49 +521,68 @@ _computeHorizontalInitCell(TDPScout & scout,
 // ----------------------------------------------------------------------------
 
 // For DPInnerColumn.
-template <typename TDPScout, typename TDPTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
-          typename TSeqHValue, typename TSeqVValue, typename TScoringScheme, typename TSpec, typename TDPMatrixLocation,
-          typename TTracebackConfig>
+template <typename TDPScout, typename TDPTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSeqHValue,
+          typename TSeqVValue,
+          typename TScoringScheme,
+          typename TSpec, typename TDPMatrixLocation, typename TGapCosts, typename TTracebackConfig, typename TExecPolicy>
 inline void
 _computeCell(TDPScout & scout,
              TDPTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
+             TDPCell & current,
+             TDPCell & diagonal,
+             TDPCell const & horizontal,
+             TDPCell & vertical,
              TSeqHValue const &,
              TSeqVValue const &,
              TScoringScheme const &,
              MetaColumnDescriptor<DPInnerColumn, PartialColumnTop> const &,
              FirstCell const &,
-             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > const &)
+             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig>, TExecPolicy> const &)
 {
-    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > TDPProfile;
-    _computeHorizontalInitCell(scout, traceMatrixNavigator, activeCell,
+    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>,
+                       TGapCosts,
+                       TracebackOn<TTracebackConfig>,
+                       TExecPolicy> TDPProfile;
+    _scoreOfCell(diagonal) = _scoreOfCell(horizontal);
+    _computeHorizontalInitCell(scout, traceMatrixNavigator, current,
                                MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), FirstCell(), TDPProfile());
+    _scoreOfCell(vertical) = _scoreOfCell(current);
+    _setVerticalScoreOfCell(vertical, _verticalScoreOfCell(current));
 }
 
 // For DPFinalColumn.
-template <typename TDPScout, typename TDPTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
-          typename TSeqHValue, typename TSeqVValue, typename TScoringScheme, typename TSpec, typename TDPMatrixLocation,
-          typename TTracebackConfig>
+template <typename TDPScout,
+          typename TDPTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSeqHValue,
+          typename TSeqVValue,
+          typename TScoringScheme,
+          typename TSpec, typename TDPMatrixLocation, typename TGapCosts, typename TTracebackConfig, typename TExecPolicy>
 inline void
 _computeCell(TDPScout & scout,
              TDPTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
+             TDPCell & current,
+             TDPCell & diagonal,
+             TDPCell const & horizontal,
+             TDPCell & vertical,
              TSeqHValue const &,
              TSeqVValue const &,
              TScoringScheme const &,
              MetaColumnDescriptor<DPFinalColumn, PartialColumnTop> const &,
              FirstCell const &,
-             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > const &)
+             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig>, TExecPolicy> const &)
 {
-    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > TDPProfile;
-    _computeHorizontalInitCell(scout, traceMatrixNavigator, activeCell,
+    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>,
+                       TGapCosts,
+                       TracebackOn<TTracebackConfig>,
+                       TExecPolicy> TDPProfile;
+    _scoreOfCell(diagonal) = _scoreOfCell(horizontal);
+    _computeHorizontalInitCell(scout, traceMatrixNavigator, current,
                                MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), FirstCell(), TDPProfile());
+    _scoreOfCell(vertical) = _scoreOfCell(current);
+    _setVerticalScoreOfCell(vertical, _verticalScoreOfCell(current));
 }
 
 // ----------------------------------------------------------------------------
@@ -544,49 +590,68 @@ _computeCell(TDPScout & scout,
 // ----------------------------------------------------------------------------
 
 // For DPInnerColumn.
-template <typename TDPScout, typename TDPTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
-          typename TSeqHValue, typename TSeqVValue, typename TScoringScheme, typename TSpec, typename TDPMatrixLocation,
-          typename TTracebackConfig>
+template <typename TDPScout,
+          typename TDPTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSeqHValue,
+          typename TSeqVValue,
+          typename TScoringScheme,
+          typename TSpec, typename TDPMatrixLocation, typename TGapCosts, typename TTracebackConfig, typename TExecPolicy>
 inline void
 _computeCell(TDPScout & scout,
              TDPTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
+             TDPCell & current,
+             TDPCell & diagonal,
+             TDPCell const & horizontal,
+             TDPCell & vertical,
              TSeqHValue const &,
              TSeqVValue const &,
              TScoringScheme const &,
              MetaColumnDescriptor<DPInnerColumn, FullColumn> const &,
              FirstCell const &,
-             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > const &)
+             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig>, TExecPolicy> const &)
 {
-    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > TDPProfile;
-    _computeHorizontalInitCell(scout, traceMatrixNavigator, activeCell,
+    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>,
+                       TGapCosts,
+                       TracebackOn<TTracebackConfig>,
+                       TExecPolicy> TDPProfile;
+    _scoreOfCell(diagonal) = _scoreOfCell(horizontal);
+    _computeHorizontalInitCell(scout, traceMatrixNavigator, current,
                                MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell(), TDPProfile());
+    _scoreOfCell(vertical) = _scoreOfCell(current);
+    _setVerticalScoreOfCell(vertical, _verticalScoreOfCell(current));
 }
 
 // For DPFinalColumn.
-template <typename TDPScout, typename TDPTraceMatrixNavigator, typename TScoreValue, typename TGapCosts,
-          typename TSeqHValue, typename TSeqVValue, typename TScoringScheme, typename TSpec, typename TDPMatrixLocation,
-          typename TTracebackConfig>
+template <typename TDPScout,
+          typename TDPTraceMatrixNavigator,
+          typename TDPCell,
+          typename TSeqHValue,
+          typename TSeqVValue,
+          typename TScoringScheme,
+          typename TSpec, typename TDPMatrixLocation, typename TGapCosts, typename TTracebackConfig, typename TExecPolicy>
 inline void
 _computeCell(TDPScout & scout,
              TDPTraceMatrixNavigator & traceMatrixNavigator,
-             DPCell_<TScoreValue, TGapCosts> & activeCell,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
-             DPCell_<TScoreValue, TGapCosts> const &,
+             TDPCell & current,
+             TDPCell & diagonal,
+             TDPCell const & horizontal,
+             TDPCell & vertical,
              TSeqHValue const &,
              TSeqVValue const &,
              TScoringScheme const &,
              MetaColumnDescriptor<DPFinalColumn, FullColumn> const &,
              FirstCell const &,
-             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > const &)
+             DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig>, TExecPolicy> const &)
 {
-    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>, TGapCosts, TracebackOn<TTracebackConfig> > TDPProfile;
-    _computeHorizontalInitCell(scout, traceMatrixNavigator, activeCell,
+    typedef DPProfile_<BandedChainAlignment_<TSpec, TDPMatrixLocation>,
+                      TGapCosts,
+                      TracebackOn<TTracebackConfig>,
+                      TExecPolicy> TDPProfile;
+    _scoreOfCell(diagonal) = _scoreOfCell(horizontal);
+    _computeHorizontalInitCell(scout, traceMatrixNavigator, current,
                                MetaColumnDescriptor<DPFinalColumn, FullColumn>(), FirstCell(), TDPProfile());
+    vertical = current;
 }
 
 // ----------------------------------------------------------------------------
@@ -680,20 +745,22 @@ void _printTraceSegments(T const & globalTraceSet)
 
 // Handles the initialization of cells for the very first dp matrix.
 template <typename TScoutState, typename TSizeH, typename TSizeV, typename TScoreScheme, typename TFreeEndGaps,
-          typename TDPMatrixLocation, typename TGapCosts, typename TTraceback>
+          typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TExecPolicy>
 inline void
 _initiaizeBeginningOfBandedChain(TScoutState & scoutState,
                                  TSizeH sizeH,
                                  TSizeV sizeV,
                                  TScoreScheme const & scoreScheme,
-                                 DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback> const &)
+                                 DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback, TExecPolicy> const &)
 {
     typedef typename TScoutState::TInitCell TInitCell;
     typedef typename Value<TInitCell, 3>::Type TDPCell;
-    typedef DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback> TDPProfile;
+    typedef DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback, TExecPolicy> TDPProfile;
 
     TDPCell dpInitCellHorizontal;
-    _computeScore(dpInitCellHorizontal, TDPCell(), TDPCell(), TDPCell(), Nothing(), Nothing(), Nothing(),
+    TDPCell dummy;
+    _computeScore(dpInitCellHorizontal, dummy, dummy, dummy,
+                  Nothing(), Nothing(), Nothing(),
                   RecursionDirectionZero(), TDPProfile());
     scoutState._nextInitializationCells.insert(TInitCell(0,0, dpInitCellHorizontal));
 
@@ -701,26 +768,31 @@ _initiaizeBeginningOfBandedChain(TScoutState & scoutState,
     {
         TDPCell prevCell = dpInitCellHorizontal;
         if (IsFreeEndGap_<TFreeEndGaps, DPFirstRow>::VALUE)
-            _computeScore(dpInitCellHorizontal, TDPCell(), TDPCell(), TDPCell(), Nothing(), Nothing(), scoreScheme,
+            _computeScore(dpInitCellHorizontal, dummy, dummy, dummy,
+                  Nothing(), Nothing(), scoreScheme,
                   RecursionDirectionZero(), TDPProfile());
         else
-            _computeScore(dpInitCellHorizontal, TDPCell(), prevCell, TDPCell(), Nothing(), Nothing(), scoreScheme,
+            _computeScore(dpInitCellHorizontal, dummy, prevCell, dummy,
+                  Nothing(), Nothing(), scoreScheme,
                   RecursionDirectionHorizontal(), TDPProfile());
         scoutState._nextInitializationCells.insert(TInitCell(activeColumn, 0, dpInitCellHorizontal));
     }
 
     TDPCell dpInitCellVertical;
-    _computeScore(dpInitCellVertical, TDPCell(), TDPCell(), TDPCell(), Nothing(), Nothing(), Nothing(),
+    _computeScore(dpInitCellVertical, dummy, dummy, dummy,
+                  Nothing(), Nothing(), Nothing(),
                   RecursionDirectionZero(), TDPProfile());
     for(TSizeV activeRow = 1; activeRow < sizeV; ++activeRow)
     {
-        TDPCell prevCell = dpInitCellVertical;
+//        TDPCell prevCell = dpInitCellVertical;
         if (IsFreeEndGap_<TFreeEndGaps, DPFirstColumn>::VALUE)
-            _computeScore(dpInitCellVertical, TDPCell(), TDPCell(), TDPCell(), Nothing(), Nothing(), scoreScheme,
-                  RecursionDirectionZero(), TDPProfile());
+            _computeScore(dpInitCellVertical, dummy, dummy, dummy,
+                          Nothing(), Nothing(), scoreScheme,
+                          RecursionDirectionZero(), TDPProfile());
         else
-            _computeScore(dpInitCellVertical, TDPCell(), TDPCell(), prevCell, Nothing(), Nothing(), scoreScheme,
-                  RecursionDirectionVertical(), TDPProfile());
+            _computeScore(dummy, dummy, dummy, dpInitCellVertical,
+                          Nothing(), Nothing(), scoreScheme,
+                          RecursionDirectionVertical(), TDPProfile());
         scoutState._nextInitializationCells.insert(TInitCell(0, activeRow, dpInitCellVertical));
     }
 
@@ -734,7 +806,7 @@ _initiaizeBeginningOfBandedChain(TScoutState & scoutState,
 // first gap-area followed by the first anchor.
 template <typename TTraceSet, typename TScoutState, typename TSeed, typename TSeqH, typename TSeqV,
           typename TScoreScheme, typename TFreeEndGaps, typename TDPMatrixLocation, typename TGaps,
-          typename TTracebackConfig>
+          typename TTracebackConfig, typename TExecPolicy>
 inline typename Value<TScoreScheme>::Type
 _initializeBandedChain(TTraceSet & globalTraceSet,
                        TScoutState & scoutState,
@@ -744,7 +816,7 @@ _initializeBandedChain(TTraceSet & globalTraceSet,
                        TSeqV const & seqV,
                        TScoreScheme const & scoreSchemeAnchor,
                        TScoreScheme const & scoreSchemeGap,
-                       DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGaps, TracebackOn<TTracebackConfig> > const & dpProfile)
+                       DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGaps, TracebackOn<TTracebackConfig>, TExecPolicy> const & dpProfile)
 {
     typedef typename Infix<TSeqH const>::Type TInfixH;
     typedef typename Infix<TSeqV const>::Type TInfixV;
@@ -800,7 +872,7 @@ _initializeBandedChain(TTraceSet & globalTraceSet,
         // Call the basic alignment function.
         score = _computeAlignment(globalTraceSet, scoutState, infixH, infixV, scoreSchemeGap, DPBandConfig<BandOff>(),
                                   DPProfile_<BandedChainAlignment_<TFreeEndGaps, BandedChainInitialDPMatrix>, TGaps,
-                                             TracebackOn<TTracebackConfig> >());
+                                             TracebackOn<TTracebackConfig>, TExecPolicy>());
     }
     else
     {
@@ -856,17 +928,17 @@ _initializeBandedChain(TTraceSet & globalTraceSet,
             resize(localTraceSet, 1);
             DPScoutState_<Default> noScout;
             score = _computeAlignment(localTraceSet[0], noScout, infixH, infixV, scoreSchemeGap, band,
-                      DPProfile_<GlobalAlignment_<TFreeEndGaps>, TGaps, TracebackOn<TTracebackConfig> >());
+                      DPProfile_<GlobalAlignment_<TFreeEndGaps>, TGaps, TracebackOn<TTracebackConfig>, TExecPolicy>());
         }
         else
             score = _computeAlignment(localTraceSet, scoutState, infixH, infixV, scoreSchemeGap, band,
-                      DPProfile_<BandedChainAlignment_<TFreeEndGaps, BandedChainInitialDPMatrix>, TGaps, TracebackOn<TTracebackConfig> >());
+                      DPProfile_<BandedChainAlignment_<TFreeEndGaps, BandedChainInitialDPMatrix>, TGaps, TracebackOn<TTracebackConfig>, TExecPolicy>());
     }
     else
     {
         if (gridEnd.i1 == length(seqH) && gridEnd.i2 == length(seqV))  // The anchor crosses the end of the matrix.
             score = _computeAlignment(localTraceSet, scoutState, infixH, infixV, scoreSchemeGap, band,
-                              DPProfile_<BandedChainAlignment_<TFreeEndGaps, BandedChainFinalDPMatrix>, TGaps, TracebackOn<TTracebackConfig> >());
+                              DPProfile_<BandedChainAlignment_<TFreeEndGaps, BandedChainFinalDPMatrix>, TGaps, TracebackOn<TTracebackConfig>, TExecPolicy>());
         else
             score = _computeAlignment(localTraceSet, scoutState, infixH, infixV, scoreSchemeGap, band, dpProfile);
     }
@@ -894,7 +966,8 @@ _initializeBandedChain(TTraceSet & globalTraceSet,
 // ----------------------------------------------------------------------------
 
 template <typename TTraceSet, typename TDPScoutState, typename TSeed, typename TSeqH, typename TSeqV,
-          typename TScoreScheme, typename TFreeEndGaps, typename TDPMatrixLocation, typename TGaps, typename TTracebackSpec>
+          typename TScoreScheme, typename TFreeEndGaps, typename TDPMatrixLocation, typename TGaps, typename TTracebackSpec,
+          typename TExecPolicy>
 inline typename Value<TScoreScheme>::Type
 _computeGapArea(TTraceSet & globalTraceSet,
                 TDPScoutState & scoutState,
@@ -903,7 +976,7 @@ _computeGapArea(TTraceSet & globalTraceSet,
                 TSeqH const & seqH,
                 TSeqV const & seqV,
                 TScoreScheme const & scoreScheme,
-                DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGaps, TracebackOn<TTracebackSpec> > const & dpProfile)
+                DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGaps, TracebackOn<TTracebackSpec>, TExecPolicy> const & dpProfile)
 {
     typedef typename Infix<TSeqH const>::Type TInfixH;
     typedef typename Infix<TSeqV const>::Type TInfixV;
@@ -955,7 +1028,8 @@ _computeGapArea(TTraceSet & globalTraceSet,
 // ----------------------------------------------------------------------------
 
 template <typename TTraceSet, typename TDPScoutState, typename TSeed, typename TSeqH, typename TSeqV,
-          typename TScoreScheme, typename TFreeEndGaps, typename TDPMatrixLocation, typename TGaps, typename TTracebackSpec>
+          typename TScoreScheme, typename TFreeEndGaps, typename TDPMatrixLocation, typename TGaps, typename TTracebackSpec,
+          typename TExecPolicy>
 inline typename Value<TScoreScheme>::Type
 _computeAnchorArea(TTraceSet & globalTraceSet,
                    TDPScoutState & scoutState,
@@ -964,7 +1038,7 @@ _computeAnchorArea(TTraceSet & globalTraceSet,
                    TSeqH const & seqH,
                    TSeqV const & seqV,
                    TScoreScheme const & scoreScheme,
-                   DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGaps, TracebackOn<TTracebackSpec> > const & dpProfile)
+                   DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGaps, TracebackOn<TTracebackSpec>, TExecPolicy> const & dpProfile)
 {
     typedef typename Infix<TSeqH const>::Type TInfixH;
     typedef typename Infix<TSeqV const>::Type TInfixV;
@@ -1027,7 +1101,8 @@ _computeAnchorArea(TTraceSet & globalTraceSet,
 // ----------------------------------------------------------------------------
 
 template <typename TTraceSet, typename TDPScoutState, typename TSeed, typename TSeqH, typename TSeqV,
-          typename TScoreScheme, typename TFreeEndGaps, typename TDPMatrixLocation, typename TGaps, typename TTracebackConfig>
+          typename TScoreScheme, typename TFreeEndGaps, typename TDPMatrixLocation, typename TGaps, typename TTracebackConfig,
+          typename TExecPolicy>
 inline typename Value<TScoreScheme>::Type
 _finishBandedChain(TTraceSet & globalTraceSet,
                    TDPScoutState & dpScoutState,
@@ -1037,7 +1112,7 @@ _finishBandedChain(TTraceSet & globalTraceSet,
                    TSeqV const & seqV,
                    TScoreScheme const & scoreSchemeAnchor,
                    TScoreScheme const & scoreSchemeGap,
-                   DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGaps, TracebackOn<TTracebackConfig> > const & dpProfile)
+                   DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGaps, TracebackOn<TTracebackConfig>, TExecPolicy> const & dpProfile)
 {
     //typedef typename Position<TSeqH const>::Type TPosH;
     //typedef typename Position<TSeqV const>::Type TPosV;
@@ -1108,7 +1183,7 @@ _finishBandedChain(TTraceSet & globalTraceSet,
             // Compute the last anchor which crosses the end of the global grid.
         clear(localTraceSet);
         TScoreValue score = _computeAlignment(localTraceSet, dpScoutState, infixH, infixV, scoreSchemeAnchor, band,
-                                  DPProfile_<BandedChainAlignment_<TFreeEndGaps, BandedChainFinalDPMatrix>, TGaps, TracebackOn<TTracebackConfig> >());
+                                  DPProfile_<BandedChainAlignment_<TFreeEndGaps, BandedChainFinalDPMatrix>, TGaps, TracebackOn<TTracebackConfig>, TExecPolicy>());
 
         _adaptLocalTracesToGlobalGrid(localTraceSet, gridBegin);
         if (!empty(localTraceSet))
@@ -1159,7 +1234,7 @@ _finishBandedChain(TTraceSet & globalTraceSet,
     clear(localTraceSet);
     score = _computeAlignment(localTraceSet, dpScoutState, suffix(seqH, gridBegin.i1), suffix(seqV,gridBegin.i2),
                               scoreSchemeGap, DPBandConfig<BandOff>(), DPProfile_<BandedChainAlignment_<TFreeEndGaps,
-                              BandedChainFinalDPMatrix>, TGaps, TracebackOn<TTracebackConfig> >());
+                              BandedChainFinalDPMatrix>, TGaps, TracebackOn<TTracebackConfig>, TExecPolicy>());
 
     _adaptLocalTracesToGlobalGrid(localTraceSet, gridBegin);
     if (!empty(localTraceSet))
@@ -1172,7 +1247,8 @@ _finishBandedChain(TTraceSet & globalTraceSet,
 // ----------------------------------------------------------------------------
 
 template <typename TGapScheme, typename TTraceTarget, typename TScoutState, typename TSequenceH, typename TSequenceV,
-          typename TScoreScheme, typename TBandSwitch, typename TAlignmentAlgorithm, typename TTraceFlag>
+          typename TScoreScheme, typename TBandSwitch, typename TAlignmentAlgorithm, typename TTraceFlag,
+          typename TExecPolicy>
 inline typename Value<TScoreScheme>::Type
 _computeAlignment(TTraceTarget & traceSegments,
                   TScoutState & scoutState,
@@ -1180,10 +1256,10 @@ _computeAlignment(TTraceTarget & traceSegments,
                   TSequenceV const & seqV,
                   TScoreScheme const & scoreScheme,
                   DPBandConfig<TBandSwitch> const & band,
-                  DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag> const & dpProfile)
+                  DPProfile_<TAlignmentAlgorithm, TGapScheme, TTraceFlag, TExecPolicy> const & dpProfile)
 {
     typedef typename Value<TScoreScheme>::Type TScoreValue;
-    typedef DPContext<TScoreValue, TGapScheme> TDPContext;
+    typedef DPContext<DPCell_<TScoreValue, TGapScheme>, typename TraceBitMap_<TScoreValue>::Type> TDPContext;
     TDPContext dpContext;
     return _computeAlignment(dpContext, traceSegments, scoutState, seqH, seqV, scoreScheme, band, dpProfile);
 }
@@ -1197,7 +1273,7 @@ _computeAlignment(TTraceTarget & traceSegments,
 // the gap between them using a standard dp algorithm.
 template <typename TTraceSet, typename TSeedSet, typename TSequenceH, typename TSequenceV, typename TScoreValue,
           typename TScoreSpecAnchor, typename TScoreSpecGap, typename TFreeEndGaps, typename TDPMatrixLocation,
-          typename TGapSpec, typename TTracebackConfig>
+          typename TGapSpec, typename TTracebackConfig, typename TExecPolicy>
 inline TScoreValue
 _computeAlignment(TTraceSet & globalTraceSet,
                   TSeedSet const & seedSet,
@@ -1207,10 +1283,8 @@ _computeAlignment(TTraceSet & globalTraceSet,
                   Score<TScoreValue, TScoreSpecGap> const & scoreSchemeGap,
                   unsigned bandExtension,
                   DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapSpec,
-                             TracebackOn<TTracebackConfig> > const & profile)
+                             TracebackOn<TTracebackConfig>, TExecPolicy> const & profile)
 {
-    //typedef DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapSpec, TracebackOn<TTracebackConfig> > TAlignmentProfile;
-
     typedef typename Position<TSequenceH>::Type TPosH;
     typedef typename Position<TSequenceV>::Type TPosV;
     typedef typename Iterator<TSeedSet const, Standard>::Type TSeedSetIterator;
@@ -1261,7 +1335,7 @@ _computeAlignment(TTraceSet & globalTraceSet,
             TTraceSet localTraceSet;
             score = _computeAlignment(localTraceSet, scoutState, suffix(seqH, gridBeginH), suffix(seqV, gridBeginV),
                               scoreSchemeGap, DPBandConfig<BandOff>(), DPProfile_<BandedChainAlignment_<TFreeEndGaps,
-                              BandedChainFinalDPMatrix>, TGapSpec, TracebackOn<TTracebackConfig> >());
+                              BandedChainFinalDPMatrix>, TGapSpec, TracebackOn<TTracebackConfig>, TExecPolicy>());
             _adaptLocalTracesToGlobalGrid(localTraceSet, Pair<TPosH, TPosV>(gridBeginH, gridBeginV));
             _glueTracebacks(globalTraceSet, localTraceSet);
         }
diff --git a/include/seqan/seeds/banded_chain_alignment_profile.h b/include/seqan/seeds/banded_chain_alignment_profile.h
index e7ea493..bbdb341 100644
--- a/include/seqan/seeds/banded_chain_alignment_profile.h
+++ b/include/seqan/seeds/banded_chain_alignment_profile.h
@@ -85,8 +85,9 @@ struct BandedChainAlignment_{};
 // Class DPMetaColumn                                              [FullColumn]
 // ----------------------------------------------------------------------------
 
-template <typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TColumnType>
-struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback>,
+template <typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TExecPolicy,
+          typename TColumnType>
+struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback, TExecPolicy>,
                     MetaColumnDescriptor<TColumnType, FullColumn> >
 {
     // If InitialColumn -> replaced, replaced, replaced
@@ -106,8 +107,9 @@ struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLoc
 // Class DPMetaColumn                                        [PartialColumnTop]
 // ----------------------------------------------------------------------------
 
-template <typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TColumnType>
-struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback>,
+template <typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TExecPolicy,
+          typename TColumnType>
+struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback, TExecPolicy>,
                     MetaColumnDescriptor<TColumnType, PartialColumnTop> >
 {
     // If InitialColumn -> replaced, replaced, replaced
@@ -127,8 +129,9 @@ struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLoc
 // Class DPMetaColumn                                      [PartialColumnMiddle]
 // ----------------------------------------------------------------------------
 
-template <typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TColumnType>
-struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback>,
+template <typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TExecPolicy,
+          typename TColumnType>
+struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback, TExecPolicy>,
                     MetaColumnDescriptor<TColumnType, PartialColumnMiddle> >
 {
     // If InitialColumn -> replaced, replaced, replaced
@@ -148,9 +151,10 @@ struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLoc
 // Class DPMetaColumn                                      [PartialColumnBottom]
 // ----------------------------------------------------------------------------
 
-template <typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TColumnType>
-struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback>,
-                    MetaColumnDescriptor<TColumnType, PartialColumnBottom> >
+template <typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTraceback, typename TExecPolicy,
+          typename TColumnType>
+struct DPMetaColumn_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTraceback, TExecPolicy>,
+                     MetaColumnDescriptor<TColumnType, PartialColumnBottom> >
 {
     // If InitialColumn -> replaced, replaced, replaced
     // If InnerColumn -> UpperDiagonal, All, All
@@ -200,7 +204,7 @@ template <typename TAlignConfig, typename TGapCosts, typename TGapsPlacement>
 struct SetupBandedChainAlignmentProfile_
 {
     typedef typename SubstituteAlignConfig_<TAlignConfig>::Type TFreeEndGaps_;
-    typedef DPProfile_<BandedChainAlignment_<TFreeEndGaps_, BandedChainInnerDPMatrix>, TGapCosts, TracebackOn<TracebackConfig_<CompleteTrace,TGapsPlacement> > > Type;
+    typedef DPProfile_<BandedChainAlignment_<TFreeEndGaps_, BandedChainInnerDPMatrix>, TGapCosts, TracebackOn<TracebackConfig_<CompleteTrace,TGapsPlacement> >, Serial> Type;
 };
 
 
diff --git a/include/seqan/seeds/banded_chain_alignment_traceback.h b/include/seqan/seeds/banded_chain_alignment_traceback.h
index 40970b2..bac939f 100644
--- a/include/seqan/seeds/banded_chain_alignment_traceback.h
+++ b/include/seqan/seeds/banded_chain_alignment_traceback.h
@@ -59,13 +59,13 @@ namespace seqan {
 // Metafunction PreferGapsAtEnd_
 // ----------------------------------------------------------------------------
 
-template <typename TFreeEndGaps, typename TMatrixSpec, typename TTracebackSpec>
+template <typename TFreeEndGaps, typename TMatrixSpec, typename TTracebackSpec, typename TExecPolicy>
 struct PreferGapsAtEnd_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, TMatrixSpec>,
-                                   AffineGaps, TTracebackSpec> > : False{};
+                                   AffineGaps, TTracebackSpec, TExecPolicy> > : False{};
 
-template <typename TFreeEndGaps, typename TTracebackSpec>
+template <typename TFreeEndGaps, typename TTracebackSpec, typename TExecPolicy>
 struct PreferGapsAtEnd_<DPProfile_<BandedChainAlignment_<TFreeEndGaps, BandedChainFinalDPMatrix>,
-                                   AffineGaps, TTracebackSpec> > : True{};
+                                   AffineGaps, TTracebackSpec, TExecPolicy> > : True{};
 
 // ============================================================================
 // Functions
@@ -235,7 +235,7 @@ _correctDPCellForAffineGaps(DPCell_<TScoreValue, AffineGaps> & dpCell, TTraceVal
 
 template<typename TTarget, typename TDPTraceMatrixNavigator, typename TDPCell, typename TScoutSpec,
          typename TSequenceH, typename TSequenceV, typename TBandFlag, typename TFreeEndGaps, typename TDPMatrixLocation,
-         typename TGapCosts, typename TTracebackSpec>
+         typename TGapCosts, typename TTracebackSpec, typename TExecPolicy>
 void _computeTraceback(TTarget & target,
                        TDPTraceMatrixNavigator & matrixNavigator,
                        unsigned maxHostPosition,
@@ -243,7 +243,7 @@ void _computeTraceback(TTarget & target,
                        TSequenceH const & seqH,
                        TSequenceV const & seqV,
                        DPBandConfig<TBandFlag> const & band,
-                       DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTracebackSpec> const & dpProfile)
+                       DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTracebackSpec, TExecPolicy> const & dpProfile)
 {
     typedef DPScout_<TDPCell, TScoutSpec> TDPScout_;
     typedef typename TDPScout_::TScoutState TScoutState_;
@@ -257,7 +257,7 @@ void _computeTraceback(TTarget & target,
     typedef typename Size<TSequenceV>::Type TSizeSeqV;
     typedef typename TraceBitMap_<>::Type TTraceValue;
 
-    if (IsSameType<TTracebackSpec, TracebackOff>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TTracebackSpec, TracebackOff>::VALUE)
         return;
 
     TSizeSeqH seqHSize = length(seqH);
@@ -283,14 +283,14 @@ void _computeTraceback(TTarget & target,
                                                           band, seqHSize, seqVSize);
 
     // Record trailing gaps if any.
-    if (IsSameType<TDPMatrixLocation, BandedChainFinalDPMatrix>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TDPMatrixLocation, BandedChainFinalDPMatrix>::VALUE)
     {
         if (tracebackCoordinator._currRow != seqVSize)
             _recordSegment(target, seqHSize, tracebackCoordinator._currRow, seqVSize - tracebackCoordinator._currRow,
-                           +TraceBitMap_<>::VERTICAL);
+                           TraceBitMap_<>::VERTICAL);
         if (tracebackCoordinator._currColumn != seqHSize)
             _recordSegment(target, tracebackCoordinator._currColumn, tracebackCoordinator._currRow, seqHSize -
-                           tracebackCoordinator._currColumn, +TraceBitMap_<>::HORIZONTAL);
+                           tracebackCoordinator._currColumn, TraceBitMap_<>::HORIZONTAL);
 
         _computeTraceback(target, matrixNavigator, position(matrixNavigator), seqHSize, seqVSize, band, dpProfile);
         return;
@@ -298,7 +298,7 @@ void _computeTraceback(TTarget & target,
 
     TSize fragmentLength = 0;
     TTarget tmp;
-    while(!_hasReachedEnd(tracebackCoordinator) && traceValue != +TraceBitMap_<>::NONE)
+    while(!_hasReachedEnd(tracebackCoordinator) && traceValue != TraceBitMap_<>::NONE)
         _doTraceback(tmp, matrixNavigator, traceValue, lastTraceValue, fragmentLength, tracebackCoordinator, TGapCosts(), TIsGapsLeft());
 
     TSignedPosition horizontalInitPos = static_cast<TSignedPosition>(tracebackCoordinator._currColumn) -
@@ -332,22 +332,22 @@ void _computeTraceback(TTarget & target,
         _computeTraceback(target, matrixNavigator, position(matrixNavigator), seqHSize, seqVSize, band, dpProfile);
     }
 
-    if (IsSameType<TDPMatrixLocation, BandedChainInitialDPMatrix>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TDPMatrixLocation, BandedChainInitialDPMatrix>::VALUE)
     {
         TPosition currCol = coordinate(matrixNavigator, +DPMatrixDimension_::HORIZONTAL);
         TPosition currRow = coordinate(matrixNavigator, +DPMatrixDimension_::VERTICAL);
 
         // Correct the row position.
-        if (IsSameType<TBandFlag, BandOn>::VALUE)
+        SEQAN_IF_CONSTEXPR (IsSameType<TBandFlag, BandOn>::VALUE)
             if (upperDiagonal(band) > 0)
                 if (currCol < tracebackCoordinator._breakpoint1)
                     if (currCol < tracebackCoordinator._breakpoint2)
                         currRow -= length(container(matrixNavigator), +DPMatrixDimension_::VERTICAL) - 1 + lowerDiagonal(band) - currCol;
         // Record leading gaps if any.
         if (currRow != 0u)
-            _recordSegment(target, 0, 0, currRow, +TraceBitMap_<>::VERTICAL);
+            _recordSegment(target, 0, 0, currRow, TraceBitMap_<>::VERTICAL);
         if (currCol != 0u)
-            _recordSegment(target, 0, 0, currCol, +TraceBitMap_<>::HORIZONTAL);
+            _recordSegment(target, 0, 0, currCol, TraceBitMap_<>::HORIZONTAL);
     }
 }
 
@@ -360,14 +360,14 @@ template <typename TTarget,
           typename TDPCell, typename TScoutSpec,
           typename TSequenceH, typename TSequenceV,
           typename TBandFlag,
-          typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTracebackSpec>
+          typename TFreeEndGaps, typename TDPMatrixLocation, typename TGapCosts, typename TTracebackSpec, typename TExecPolicy>
 void _computeTraceback(StringSet<TTarget> & targetSet,
                        TDPTraceMatrixNavigator & matrixNavigator,
                        DPScout_<TDPCell, TScoutSpec> & dpScout,
                        TSequenceH const & seqH,
                        TSequenceV const & seqV,
                        DPBandConfig<TBandFlag> const & band,
-                       DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTracebackSpec> const & dpProfile)
+                       DPProfile_<BandedChainAlignment_<TFreeEndGaps, TDPMatrixLocation>, TGapCosts, TTracebackSpec, TExecPolicy> const & dpProfile)
 {
     typedef DPScout_<TDPCell, TScoutSpec> TDPScout;
     typedef typename TDPScout::TMaxHostPositionString TMaxHostPositions;
diff --git a/include/seqan/seeds/seeds_global_chaining.h b/include/seqan/seeds/seeds_global_chaining.h
index 5a6e867..ee84323 100644
--- a/include/seqan/seeds/seeds_global_chaining.h
+++ b/include/seqan/seeds/seeds_global_chaining.h
@@ -62,6 +62,23 @@ typedef Tag<SparseChaining_> SparseChaining;
 // Functions
 // ===========================================================================
 
+template <typename TIntermediate>
+inline bool _checkScoreInvariant(TIntermediate const & list)
+{
+    if (list.empty())
+        return true;
+    auto it = list.begin();
+    auto score = it->i2;
+    ++it;
+    for (; it != list.end(); ++it)
+    {
+        if (score > it->i2)
+            return false;
+        score = it->i2;
+    }
+    return true;
+}
+
 /*!
  * @fn chainSeedsGlobally
  * @headerfile <seqan/seeds.h>
@@ -97,6 +114,13 @@ typedef Tag<SparseChaining_> SparseChaining;
  */
 
 // TODO(holtgrew): Implement scored!
+// NOTE(rrahn): Some general notes regarding the sparse chaining algorithm by Gusfield.
+// From the text it is hard to follow the correct algorithm, as one usually expects the y-coordinates to
+// be increasing integers (sequence positions). However, the algorithm assumes the coordinates of the
+// rectangles to be placed in the fourth quadrant of the cartesian coordinate system (negative y-coordinates).
+// To adapt the algorithm for the positive sequence space we sort the y-coordinates in *L* in ascending order.
+// We then can use lower_bound and upper_bound on the sorted set to find the corresponding seed j as described in
+// the algorithm.
 template <typename TTargetContainer, typename TSeed, typename TSeedSetSpec>
 void
 chainSeedsGlobally(
@@ -153,8 +177,8 @@ chainSeedsGlobally(
     // -----------------------------------------------------------------------
     // Step 2: Build the chain.
     // -----------------------------------------------------------------------
-    // We build a list of "intermediate solutions".  Each such
-    // solution is represented by the triple (end position in dim1,
+    // We build a list of "intermediate solutions" (referred to as *L* in the Gusfield book).
+    // Each such solution is represented by the triple (end position in dim1,
     // value of best chain so far, last seed of the chain).
     typedef Triple<TPosition, TSize, unsigned> TIntermediateSolution;
     typedef std::multiset<TIntermediateSolution> TIntermediateSolutions;
@@ -162,89 +186,99 @@ chainSeedsGlobally(
 
     // For all interval points...
     TIntermediateSolutions intermediateSolutions;
-    for (TIntervalPointsIterator it = begin(intervalPoints), itEnd = end(intervalPoints); it != itEnd; ++it) {
+    for (TIntervalPointsIterator it_k = begin(intervalPoints), itEnd = end(intervalPoints); it_k != itEnd; ++it_k) {
         // The seed belonging ot the interval point is seed k.
-        TSeed const & seedK = seeds[it->i3];
+        TSeed const & seed_k = seeds[it_k->i3];
 
         // std::cout << "Processing interval point (" << it->i1 << ", " << it->i2 << ", " << it->i3 << ")" << std::endl;
-        if (it->i2) {  // Is is begin point.
-            // Find the closest seed (in dimension 1) to seed k with an
-            // entry in intermediateSolutions whose end coordinate in
-            // dimension 1 is <= the begin coordinate in dimension 1
-            // of seedK.
+        if (it_k->i2) {  // Is is begin point.
+            // Find the closest seed j (in y-dimension) with an
+            // entry in L whose end coordinate is less or equal the begin position of k.
             //
             // STL gives us upper_bound which returns a pointer to the
             // *first* one that compares greater than the reference
             // one.  Searching for the this one and decrementing the
             // result iterator gives the desired result.
-            TIntermediateSolution referenceSolution(beginPositionV(seedK), std::numeric_limits<TSize>::max(), std::numeric_limits<unsigned>::max());
-            // std::cout << "    intermediateSolutions.upper_bound(" << beginPositionV(seedK) << ")" << std::endl;
-            TIntermediateSolutionsIterator itJ = intermediateSolutions.upper_bound(referenceSolution);
-            if (itJ == intermediateSolutions.begin()) {
-                if (intermediateSolutions.size() > 0 &&
-                    intermediateSolutions.rbegin()->i1 <= beginPositionV(seedK)) {
-                    itJ = intermediateSolutions.end();
-                    --itJ;
-                } else {
-                    continue;
-                }
-            } else {
-                SEQAN_ASSERT_GT(intermediateSolutions.size(), 0u);  // TODO(holtgrew): Remove this assertion?
-                --itJ;
+            TIntermediateSolution referenceSolution(beginPositionV(seed_k), std::numeric_limits<TSize>::max(), std::numeric_limits<unsigned>::max());
+            // std::cout << "    intermediateSolutions.upper_bound(" << beginPositionV(seed_k) << ")" << std::endl;
+            TIntermediateSolutionsIterator it_j = intermediateSolutions.upper_bound(referenceSolution);
+
+            // Special case not dealt with in the book: If L is empty or there is no chain
+            // that ends before k begins, simply continue with the next point in I.
+            if (intermediateSolutions.empty() || it_j == intermediateSolutions.begin())
+            {
+                continue;
             }
-            // std::cout << "     --> " << seeds[itJ->i3] << std::endl;
+            // Go to the last value in L, i.e. l_j <= h_k.
+            --it_j;
+            // std::cout << "     --> " << seeds[it_j->i3] << std::endl;
             // Now, we have found such a seed j.
-            SEQAN_ASSERT_LEQ(endPositionV(seeds[itJ->i3]), endPositionV(seedK));
+            SEQAN_ASSERT_LEQ(endPositionV(seeds[it_j->i3]), beginPositionV(seed_k));
             // Update the intermediate solution value for k and set predecessor.
-            qualityOfChainEndingIn[it->i3] += itJ->i2;
+            qualityOfChainEndingIn[it_k->i3] += it_j->i2;
             // std::cout << "  UPDATE qualityOfChainEndingIn[" << it->i3 << "] == " << qualityOfChainEndingIn[it->i3] << std::endl;
-            predecessor[it->i3] = itJ->i3;
+            predecessor[it_k->i3] = it_j->i3;
             // std::cout << "         predecessor[" << it->i3 << "] == " << itJ->i3 << std::endl;
         } else {  // Is end point.
-            // Search for the first triple in intermediateSolutions
-            // where the end coordinate in dimension 1 is >= end
-            // coordinate in dimension 1 for seed k.  The corresponding
-            // seed is seed j.
+            // Search for the first triple j in L with l_j >= l_k.
+            // Or to put it in differently, find the first chain that ends
+            // left and below the chain that ends in k. These are other possible solutions,
+            // that either result in a better score or must be deleted as the score of the chain ending in k
+            // is bigger. Hence, every other seed that could connect to both j and k, prefers the one with the higher
+            // score.
             //
-            // We work with upper_bound here which gives us the first
-            // value that is > so we have to work around this to get
-            // >= again...
-            SEQAN_ASSERT_GT(endPositionV(seedK), 0u);
-            TIntermediateSolution referenceSolution(endPositionV(seedK), 0, std::numeric_limits<unsigned>::max());
-            TIntermediateSolutionsIterator itSol = intermediateSolutions.upper_bound(referenceSolution);
-            if (itSol == intermediateSolutions.end()) {
-                // None found.  Insert a new triple for seed k.
-                TIntermediateSolution sol(endPositionV(seedK), qualityOfChainEndingIn[it->i3], it->i3);
-                // std::cout << "  INSERT (" << sol.i1 << ", " << sol.i2 << ", " << sol.i3 << ") " << __LINE__ << std::endl;
-                intermediateSolutions.insert(sol);
-            } else {
+            // We can use the lower_bound, which gives the first triple j such that l_j >= l_k
+            SEQAN_ASSERT_GT(endPositionV(seed_k), 0u);
+            TIntermediateSolution referenceSolution(endPositionV(seed_k), 0, std::numeric_limits<unsigned>::max());
+            TIntermediateSolutionsIterator it_j = intermediateSolutions.lower_bound(referenceSolution);
+
+            // If there was a valid solution in L...
+            if (it_j != intermediateSolutions.end())
+            {
                 // Found this intermediate solution.
-                SEQAN_ASSERT_GEQ(itSol->i1, endPositionV(seedK));
-                TSeed const & seedJ = seeds[itSol->i3];
-                // Possibly start a new chain at k if the end1 is
-                // before the end1 of the chain ending in j or they
-                // end at the same coordinate in dim1 but k already
-                // has a higher quality than the whole chaing ending
-                // at j.
-                if (endPositionV(seedJ) > endPositionV(seedK) ||
-                    (endPositionV(seedJ) == endPositionV(seedK) && qualityOfChainEndingIn[it->i3] > itSol->i2)) {
-                    TIntermediateSolution sol(endPositionV(seedK), qualityOfChainEndingIn[it->i3], it->i3);
+                SEQAN_ASSERT_GEQ(it_j->i1, endPositionV(seed_k));
+                TSeed const & seed_j = seeds[it_j->i3];
+                // ... start a new chain at k if the vertical end of k is
+                // above the vertical end of the chain ending in j or if
+                // both k and j end at the same vertical position, while
+                // the score of the chain ending in k is bigger than the
+                // score of the chain ending in j.
+                if (endPositionV(seed_j) > endPositionV(seed_k) ||
+                    (endPositionV(seed_j) == endPositionV(seed_k) && qualityOfChainEndingIn[it_k->i3] > it_j->i2))
+                {
+                    TIntermediateSolution sol(endPositionV(seed_k), qualityOfChainEndingIn[it_k->i3], it_k->i3);
                     // std::cout << "  INSERT (" << sol.i1 << ", " << sol.i2 << ", " << sol.i3 << ")" << __LINE__  << std::endl;
                     intermediateSolutions.insert(sol);
-                }
-            }
 
-            // Delete all intermediate solutions where end1 >= end1 of k and have a lower quality than k.
-            TIntermediateSolutionsIterator itDel = intermediateSolutions.upper_bound(referenceSolution);
-            TIntermediateSolutionsIterator itDelEnd = intermediateSolutions.end();
-            while (itDel != itDelEnd) {
-                TIntermediateSolutionsIterator ptr = itDel;
-                ++itDel;
-                if (qualityOfChainEndingIn[it->i3] > ptr->i2) {
-                    // std::cout << "  ERASE (" << ptr->i1 << ", " << ptr->i2 << ", " << ptr->i3 << ")" << std::endl;
-                    intermediateSolutions.erase(ptr);
+                    // Delete all intermediate solutions where end1 >= end1 of k and have a lower score than k
+                    // to ensure that the invariant of V(j) >= V(j'), with j' <= j holds.
+                    // Roughly then, there is no chain ending in a seed below the seed_k, that has a lower score
+                    // than the chain ending in seed_k. Thus the last value in `intermediateSolutions` will
+                    // always point to the optimal chain.
+                    TIntermediateSolutionsIterator itDel = intermediateSolutions.upper_bound(referenceSolution);
+                    TIntermediateSolutionsIterator itDelEnd = intermediateSolutions.end();
+                    while (itDel != itDelEnd)
+                    {
+                        TIntermediateSolutionsIterator ptr = itDel;
+                        ++itDel;
+                        if (qualityOfChainEndingIn[it_k->i3] > ptr->i2)
+                        {
+                            // std::cout << "  ERASE (" << ptr->i1 << ", " << ptr->i2 << ", " << ptr->i3 << ")" << std::endl;
+                            intermediateSolutions.erase(ptr);
+                        }
+                    }
                 }
+            } // ... otherwise, add a triple for k in L if either L is empty or the last triple in
+              // L has a lower score than the chain ending in k.
+            else if (intermediateSolutions.empty() || (--it_j)->i2 < qualityOfChainEndingIn[it_k->i3])
+            {
+                // None found.  Insert a new triple for seed k.
+                TIntermediateSolution sol(endPositionV(seed_k), qualityOfChainEndingIn[it_k->i3], it_k->i3);
+                // std::cout << "  INSERT (" << sol.i1 << ", " << sol.i2 << ", " << sol.i3 << ") " << __LINE__ << std::endl;
+                intermediateSolutions.insert(sol);
             }
+            // Check if the invariant holds, that the scores in L are in a non-decreasing order.
+            SEQAN_ASSERT(_checkScoreInvariant(intermediateSolutions));
         }
     }
 
diff --git a/include/seqan/sequence/string_alloc.h b/include/seqan/sequence/string_alloc.h
index 3f485ec..46b11f7 100644
--- a/include/seqan/sequence/string_alloc.h
+++ b/include/seqan/sequence/string_alloc.h
@@ -78,7 +78,9 @@ public:
         SEQAN_ASSERT_LEQ_MSG(data_begin, data_end, "String end is before begin!");
     }
 
-    template <typename TSource>
+    template <typename TSource,
+              typename Dummy = void,
+              typename = std::enable_if_t<std::is_convertible<typename Value<TSource>::Type,TValue>::value, Dummy> >
     String(TSource & source)
         : data_begin(0),
           data_end(0),
@@ -89,7 +91,9 @@ public:
         SEQAN_ASSERT_LEQ_MSG(data_begin, data_end, "String end is before begin!");
     }
 
-    template <typename TSource>
+    template <typename TSource,
+              typename Dummy = void,
+              typename = std::enable_if_t<std::is_convertible<typename Value<TSource>::Type, TValue>::value, Dummy> >
     String(TSource const & source)
         : data_begin(0),
           data_end(0),
@@ -140,7 +144,10 @@ public:
         SEQAN_ASSERT_LEQ_MSG(data_begin, data_end, "String end is before begin!");
     }
 
-    template <typename TSource, typename TSize>
+    template <typename TSource,
+              typename TSize,
+              typename Dummy = void,
+              typename = std::enable_if_t<std::is_convertible<typename Value<TSource>::Type, TValue>::value, Dummy> >
     String(TSource & source, TSize limit)
             : data_begin(0),
               data_end(0),
@@ -151,7 +158,10 @@ public:
         SEQAN_ASSERT_LEQ_MSG(data_begin, data_end, "String end is before begin!");
     }
 
-    template <typename TSource, typename TSize>
+    template <typename TSource,
+              typename TSize,
+              typename Dummy = void,
+              typename = std::enable_if_t<std::is_convertible<typename Value<TSource>::Type, TValue>::value, Dummy> >
     String(TSource const & source, TSize limit)
             : data_begin(0),
               data_end(0),
@@ -163,7 +173,9 @@ public:
     }
 
 
-    template <typename TSource>
+    template <typename TSource,
+              typename Dummy = void,
+              typename = std::enable_if_t<std::is_convertible<typename Value<TSource>::Type, TValue>::value, Dummy> >
     inline
     String & operator=(TSource const & source)
     {
diff --git a/include/seqan/sequence/string_base.h b/include/seqan/sequence/string_base.h
index 3b10a6f..7012040 100644
--- a/include/seqan/sequence/string_base.h
+++ b/include/seqan/sequence/string_base.h
@@ -2034,6 +2034,30 @@ operator<<(TStream & target,
     return target;
 }
 
+// A specialization needed to avoid an ambiguous call combined with googletest.
+//
+// We use `std::basic_ostream<char>` instead of `std::ostream`, because we would
+// need to redefine a lot of CONCEPTS within seqan. Unfortunately,
+// `std::basic_ostream<char>` does not work, because `directionIterator` might not
+// be included yet (defined in <iter_stream.h>). Thus using `TChar` with the
+// restriction that it can only be `char`.
+//
+// We do not use the more generic `std::basic_ostream<TChar, Traits>` type,
+// because this would clash with other overloads of `<<` where `TSpec` within
+// String<TValue, ...> is more specific. E.g. in the case of `TSpec =
+// Journaled<...>`.
+//
+// https://github.com/seqan/seqan/issues/2182
+template <typename TChar, typename TValue>
+inline SEQAN_FUNC_ENABLE_IF(IsSameType<TChar, char>, std::basic_ostream<TChar> &)
+operator<<(std::basic_ostream<TChar> & target,
+           String<TValue> const & source)
+{
+    auto it = directionIterator(target, Output());
+    write(it, source);
+    return target;
+}
+
 // ----------------------------------------------------------------------------
 // Function operator>>() for streams.
 // ----------------------------------------------------------------------------
diff --git a/include/seqan/sequence/string_set_concat_direct.h b/include/seqan/sequence/string_set_concat_direct.h
index 83285af..76d934d 100644
--- a/include/seqan/sequence/string_set_concat_direct.h
+++ b/include/seqan/sequence/string_set_concat_direct.h
@@ -103,21 +103,21 @@ public:
     {}
 
     template <typename TOtherString, typename TOtherSpec>
-    StringSet(StringSet<TOtherString, TOtherSpec> &other)
+    StringSet(StringSet<TOtherString, TOtherSpec> & other)
     {
         _initStringSetLimits(*this);
         assign(*this, other);
     }
 
     template <typename TOtherString, typename TOtherSpec>
-    StringSet(StringSet<TOtherString, TOtherSpec> const &other)
+    StringSet(StringSet<TOtherString, TOtherSpec> const & other)
     {
         _initStringSetLimits(*this);
         assign(*this, other);
     }
 
     template <typename TOtherSpec>
-    StringSet(String<TString, TOtherSpec> const &other)
+    StringSet(String<TString, TOtherSpec> const & other)
     {
         _initStringSetLimits(*this);
         assign(*this, other);
diff --git a/include/seqan/sequence/string_set_owner.h b/include/seqan/sequence/string_set_owner.h
index abdac6b..f4cc8b8 100644
--- a/include/seqan/sequence/string_set_owner.h
+++ b/include/seqan/sequence/string_set_owner.h
@@ -91,7 +91,7 @@ public:
     }
 
     template <typename TOtherString, typename TOtherSpec>
-    StringSet(StringSet<TOtherString, TOtherSpec> const &other) :
+    StringSet(StringSet<TOtherString, TOtherSpec> const & other) :
         limitsValid(true)
     {
         _initStringSetLimits(*this);
@@ -99,7 +99,7 @@ public:
     }
 
     template <typename TOtherSpec>
-    StringSet(String<TString, TOtherSpec> const &other) :
+    StringSet(String<TString, TOtherSpec> const & other) :
         limitsValid(true)
     {
         _initStringSetLimits(*this);
diff --git a/include/seqan/simd.h b/include/seqan/simd.h
index b2f0081..70a4b8b 100644
--- a/include/seqan/simd.h
+++ b/include/seqan/simd.h
@@ -99,10 +99,13 @@
 #endif // defined(COMPILER_GCC) && __GNUC__ <= 4
 
 // Define maximal size of vector in byte.
-#if defined(SEQAN_SEQANSIMD_ENABLED) && defined(__AVX512F__)
+#if defined(SEQAN_SEQANSIMD_ENABLED) && defined(__AVX512F__) && defined(COMPILER_GCC)
+    // gcc compiler supports auto vectorization
+    #define SEQAN_SIZEOF_MAX_VECTOR 64
+#elif 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 " \
+        #pragma message("SEQAN_SIMD doesn't support AVX512 (except gcc), 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
@@ -118,13 +121,17 @@
 #include "simd/simd_base_seqan_impl.h"
 
 #if defined(SEQAN_SEQANSIMD_ENABLED)
-    #if defined(__SSE4_2__)
+    #if SEQAN_SIZEOF_MAX_VECTOR >= 16
     #include "simd/simd_base_seqan_impl_sse4.2.h"
-    #endif // defined(SEQAN_SSE4)
+    #endif // SEQAN_SIZEOF_MAX_VECTOR >= 16
 
-    #if defined(__AVX2__)
+    #if SEQAN_SIZEOF_MAX_VECTOR >= 32
     #include "simd/simd_base_seqan_impl_avx2.h"
-    #endif // defined(__AVX2__)
+    #endif // SEQAN_SIZEOF_MAX_VECTOR >= 32
+
+    #if SEQAN_SIZEOF_MAX_VECTOR >= 64
+    #include "simd/simd_base_seqan_impl_avx512.h"
+    #endif // SEQAN_SIZEOF_MAX_VECTOR >= 64
 
     #include "simd/simd_base_seqan_interface.h"
 #endif // defined(SEQAN_SEQANSIMD_ENABLED)
diff --git a/include/seqan/simd/simd_base.h b/include/seqan/simd/simd_base.h
index 938e37c..4bb8ed2 100644
--- a/include/seqan/simd/simd_base.h
+++ b/include/seqan/simd/simd_base.h
@@ -68,17 +68,46 @@ struct LENGTH<SimdVector<TValue, LENGTH_> const> :
 
 // define a concept and its models
 // they allow us to define generic vector functions
-SEQAN_CONCEPT(SimdVectorConcept, (TSimdVector)) {
-    typedef typename Reference<TSimdVector>::Type TReference;
+SEQAN_CONCEPT(SimdMaskVectorConcept, (TSimdMaskVector))
+{
+    typedef typename Reference<TSimdMaskVector>::Type TReference;
 
-    TSimdVector a;
+    TSimdMaskVector a;
 
-    SEQAN_CONCEPT_USAGE(SimdVectorConcept)
+    SEQAN_CONCEPT_USAGE(SimdMaskVectorConcept)
     {
         static_assert(IsSameType<decltype(a[0]), TReference>::VALUE, "Type of a[] should be the same as the reference type of a.");
     }
 };
 
+SEQAN_CONCEPT_REFINE(SimdVectorConcept, (TSimdVector), (SimdMaskVectorConcept))
+{
+    SEQAN_CONCEPT_USAGE(SimdVectorConcept)
+    {}
+};
+
+template <typename TSimdVector, typename TIsSimdVec>
+struct SimdMaskVectorImpl {
+    using Type = Nothing;
+};
+
+/**
+ * SimdMaskVector is the return type of all logical operations of simd vectors
+ * like comparisons.
+ *
+ * ```
+ * using TSimdVector = SimdVector<uint32_t, 4>::Type;
+ * using TSimdMaskVector = SimdMaskVector<TSimdVector>::Type;
+ *
+ * TSimdVector vec1 {2, 4, 8, 16}, vec2 {16, 8, 4, 2};
+ * TSimdMaskVector cmp = vec1 > vec2; // cmp = {false, false, true, true}
+ * ```
+ */
+template <typename TSimdVector>
+struct SimdMaskVector : SimdMaskVectorImpl<TSimdVector, typename Is<SimdVectorConcept<TSimdVector> >::Type >
+{
+};
+
 template <typename TSimdVector, typename TIsSimdVec>
 struct SimdSwizzleVectorImpl;
 
@@ -166,9 +195,9 @@ clearVector(TSimdVector & vector);
  *     c[i] = a;
  * ```
  */
-template <typename TSimdVector, typename TValue>
+template <typename TSimdVector>
 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-createVector(TValue const x);
+createVector(typename Value<TSimdVector>::Type const x);
 
 /**
  * ```
@@ -188,36 +217,59 @@ fillVector(TSimdVector & vector, TValue const... args);
 
 /**
  * ```
- * c = cmpEq(a, b);
+ * auto c = cmpEq(a, b);
  *
  * // same as
  *
- * c = a == b;
+ * auto c = a == b;
+ * ```
+ *
+ * NOTE:
+ * The type of c might change from unsigned to signed if auto is used
+ *
+ * ```
+ * using TSimdVector = SimdVector<uint32_t, 4>::Type;
+ * TSimdVector a, b;
+ *
+ * auto c = a == b; // type of c might change to SimdVector<int32_t, 4>::Type
+ * TSimdVector d = a == b; // has the same type
  * ```
  */
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 cmpEq (TSimdVector const & a, TSimdVector const & b);
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 operator==(TSimdVector const & a, TSimdVector const & b);
 
 /**
  * ```
- * c = cmpGt(a, b);
+ * auto c = cmpGt(a, b);
  *
  * // same as
  *
- * c = a > b;
+ * auto c = a > b;
+ * ```
+ *
+ * NOTE:
+ * The type of c might change from unsigned to signed if auto is used
+ *
+ * ```
+ * using TSimdVector = SimdVector<uint32_t, 4>::Type;
+ * using TSimdMaskVector = SimdMaskVector<TSimdVector>::Type;
+ * TSimdVector a, b;
+ *
+ * auto c = a > b; // type of c might change to SimdVector<int32_t, 4>::Type
+ * TSimdMaskVector d = a > b; // has the same type
  * ```
  */
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 cmpGt (TSimdVector const & a, TSimdVector const & b);
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 operator>(TSimdVector const & a, TSimdVector const & b);
 
 template <typename TSimdVector>
@@ -312,12 +364,27 @@ 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)
+inline SEQAN_FUNC_ENABLE_IF(Is<NumberConcept<TSimdVector>>, TSimdVector)
 createVector(TValue const x)
 {
     return x;
 }
 
-} // namespace seqan
+// --------------------------------------------------------------------------
+// Function print()
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector>
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdMaskVectorConcept<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_H_
diff --git a/include/seqan/simd/simd_base_seqan_impl.h b/include/seqan/simd/simd_base_seqan_impl.h
index ff224df..ee17b9f 100644
--- a/include/seqan/simd/simd_base_seqan_impl.h
+++ b/include/seqan/simd/simd_base_seqan_impl.h
@@ -48,8 +48,12 @@
 #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!"
+#elif defined(SEQAN_SIMD_ENABLED)
+  #pragma message "You are trying to build with -DSEQAN_SIMD_ENABLED, which might be " \
+  "auto-defined if AVX or SSE was enabled (e.g. -march=native, -msse4, ...), " \
+  "but we only support x86/x86-64 architectures for SIMD vectorization! " \
+  "You might want to use UME::SIMD (https://github.com/edanor/umesimd) combined " \
+  "with -DSEQAN_UMESIMD_ENABLED for a different SIMD backend."
 #endif
 
 namespace seqan {
@@ -115,6 +119,13 @@ template <int VEC_SIZE, int LENGTH = 0, typename SCALAR_TYPE = void>
 struct SimdParams_
 {};
 
+// internal traits meta-function to capture correct the mask type.
+template <typename TSimdVector, typename TSimdParams>
+struct SimdVectorTraits
+{
+    using MaskType = TSimdVector;
+};
+
 // internal struct to specialize for matrix parameters
 template <int ROWS, int COLS, int BITS_PER_VALUE>
 struct SimdMatrixParams_
diff --git a/include/seqan/simd/simd_base_seqan_impl_avx2.h b/include/seqan/simd/simd_base_seqan_impl_avx2.h
index 05d2d80..9ecffd1 100644
--- a/include/seqan/simd/simd_base_seqan_impl_avx2.h
+++ b/include/seqan/simd/simd_base_seqan_impl_avx2.h
@@ -135,20 +135,9 @@ _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
 }
 
 // --------------------------------------------------------------------------
diff --git a/include/seqan/simd/simd_base_seqan_impl_avx512.h b/include/seqan/simd/simd_base_seqan_impl_avx512.h
new file mode 100644
index 0000000..7086ae2
--- /dev/null
+++ b/include/seqan/simd/simd_base_seqan_impl_avx512.h
@@ -0,0 +1,284 @@
+// ==========================================================================
+//                 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 AVX512
+// ==========================================================================
+
+#ifndef SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_AVX512_H_
+#define SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_AVX512_H_
+
+namespace seqan {
+
+// SimdParams_<64, 64>: 512bit = 64 elements * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector64Char,     char,           64)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector64SChar,    signed char,    64)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector64UChar,    unsigned char,  64)
+
+// SimdParams_<64, 32>: 512bit = 32 elements * 2 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector32Short,    short,          64)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector32UShort,   unsigned short, 64)
+
+// SimdParams_<64, 16>: 512bit = 16 elements * 4 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16Int,      int,            64)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector16UInt,     unsigned int,   64)
+
+// SimdParams_<64, 8>: 512bit = 8 elements * 8 * 8bit
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8Int64,     int64_t,        64)
+SEQAN_DEFINE_SIMD_VECTOR_(SimdVector8UInt64,    uint64_t,       64)
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+// ============================================================================
+// AVX512 wrappers (512bit vectors)
+// ============================================================================
+
+// --------------------------------------------------------------------------
+// _fillVector (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L, typename TValue>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue> const & x,
+            std::index_sequence<0> const &,
+            SimdParams_<64, L>)
+{
+    vector = createVector<TSimdVector>(std::get<0>(x));
+}
+
+template <typename TSimdVector, int L, typename ...TValue, size_t ...INDICES>
+inline void
+_fillVector(TSimdVector & vector,
+            std::tuple<TValue...> const & args,
+            std::index_sequence<INDICES...> const &,
+            SimdParams_<64, L>)
+{
+    using TSimdValue = typename Value<TSimdVector>::Type;
+    vector = TSimdVector{static_cast<TSimdValue>(std::get<INDICES>(args))...};
+}
+
+// --------------------------------------------------------------------------
+// _clearVector (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline void _clearVector(TSimdVector & vector, SimdParams_<64, L>)
+{
+    vector = TSimdVector{};
+}
+
+// --------------------------------------------------------------------------
+// _createVector (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TValue, int L>
+inline TSimdVector _createVector(TValue const x, SimdParams_<64, L>)
+{
+    using TValue_ = typename Value<TSimdVector>::Type;
+    return TSimdVector{} + static_cast<TValue_>(x);
+}
+
+// --------------------------------------------------------------------------
+// _cmpEq (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _cmpEq(TSimdVector & a, TSimdVector & b, SimdParams_<64, L>)
+{
+    return a == b;
+}
+
+// bad auto-vectorization for gcc
+#ifndef __AVX512BW__
+template <typename TSimdVector>
+inline TSimdVector _cmpEq(TSimdVector const & a, TSimdVector const & b, SimdParams_<64, 32>)
+{
+    auto aLow = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, a), 0);
+    auto bLow = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, b), 0);
+    auto cmpLow = _mm256_cmpeq_epi16(aLow, bLow);
+
+    auto aHigh = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, a), 1);
+    auto bHigh = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, b), 1);
+    auto cmpHigh = _mm256_cmpeq_epi16(aHigh, bHigh);
+
+    auto result = _mm512_broadcast_i64x4(cmpLow);
+    result = _mm512_inserti64x4(result, cmpHigh, 1);
+    return SEQAN_VECTOR_CAST_(TSimdVector, result);
+}
+#endif
+
+// --------------------------------------------------------------------------
+// _cmpGt (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L, typename TValue>
+inline TSimdVector _cmpGt(TSimdVector & a, TSimdVector & b, SimdParams_<64, L, TValue>)
+{
+    return a > b;
+}
+
+// --------------------------------------------------------------------------
+// _bitwiseAndNot (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _bitwiseAndNot(TSimdVector & a, TSimdVector & b, SimdParams_<64, L>)
+{
+    return (~a & b);
+}
+
+// --------------------------------------------------------------------------
+// _max (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L, typename TValue>
+inline TSimdVector _max(TSimdVector & a, TSimdVector & b, SimdParams_<64, L, TValue>)
+{
+    return a > b ? a : b;
+}
+
+// --------------------------------------------------------------------------
+// _min (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L, typename TValue>
+inline TSimdVector _min(TSimdVector & a, TSimdVector & b, SimdParams_<64, L, TValue>)
+{
+    return a < b ? a : b;
+}
+
+// --------------------------------------------------------------------------
+// _blend (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, typename TSimdVectorMask, int L>
+inline TSimdVector _blend(TSimdVector const & a, TSimdVector const & b, TSimdVectorMask const & mask, SimdParams_<64, L>)
+{
+    return mask ? b : a;
+}
+
+// bad auto-vectorization for gcc
+#ifndef __AVX512BW__
+template <typename TSimdVector, typename TSimdVectorMask>
+inline TSimdVector _blend(TSimdVector const & a, TSimdVector const & b, TSimdVectorMask const & mask, SimdParams_<64, 32>)
+{
+    auto aLow = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, a), 0);
+    auto bLow = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, b), 0);
+    auto maskLow = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, mask), 0);
+    auto blendLow = _mm256_blendv_epi8(aLow, bLow, maskLow);
+
+    auto aHigh = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, a), 1);
+    auto bHigh = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, b), 1);
+    auto maskHigh = _mm512_extracti64x4_epi64(SEQAN_VECTOR_CAST_(const __m512i&, mask), 1);
+    auto blendHigh = _mm256_blendv_epi8(aHigh, bHigh, maskHigh);
+
+    auto result = _mm512_broadcast_i64x4(blendLow);
+    result = _mm512_inserti64x4(result, blendHigh, 1);
+    return SEQAN_VECTOR_CAST_(TSimdVector, result);
+}
+#endif
+
+// --------------------------------------------------------------------------
+// _storeu (512bit)
+// --------------------------------------------------------------------------
+
+template <typename T, typename TSimdVector, int L>
+inline void _storeu(T * memAddr, TSimdVector & vec, SimdParams_<64, L>)
+{
+    constexpr auto length = LENGTH<TSimdVector>::VALUE;
+    for (unsigned i = 0; i < length; i++)
+        memAddr[i] = vec[i];
+}
+
+// ----------------------------------------------------------------------------
+// Function _load() 512bit
+// ----------------------------------------------------------------------------
+
+template <typename TSimdVector, typename T, int L>
+inline TSimdVector _load(T const * memAddr, SimdParams_<64, L>)
+{
+    constexpr auto length = LENGTH<TSimdVector>::VALUE;
+    TSimdVector result;
+    for (unsigned i = 0; i < length; i++)
+        result[i] = memAddr[i];
+    return result;
+}
+
+// --------------------------------------------------------------------------
+// _shiftRightLogical (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector, int L>
+inline TSimdVector _shiftRightLogical(TSimdVector const & vector, const int imm, SimdParams_<64, L>)
+{
+    return vector >> imm;
+}
+
+// --------------------------------------------------------------------------
+// _gather (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TValue, typename TSimdVector, typename TSize, TSize SCALE, int L>
+inline TSimdVector
+_gather(TValue const * memAddr,
+        TSimdVector const & idx,
+        std::integral_constant<TSize, SCALE> const & /*scale*/,
+        SimdParams_<64, L>)
+{
+    constexpr auto length = LENGTH<TSimdVector>::VALUE;
+    TSimdVector result;
+    for (unsigned i = 0; i < length; i++)
+        result[i] = memAddr[idx[i]];
+    return result;
+}
+
+// --------------------------------------------------------------------------
+// _shuffleVector (512bit)
+// --------------------------------------------------------------------------
+
+template <typename TSimdVector1, typename TSimdVector2, int L>
+inline TSimdVector1
+_shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices, SimdParams_<64, L>, SimdParams_<64, 64>)
+{
+    constexpr auto length = seqan::LENGTH<TSimdVector1>::VALUE;
+    TSimdVector1 result{};
+    for(unsigned i = 0u; i < length; ++i)
+        result[i] = vector[indices[i]];
+    return result;
+}
+
+} // namespace seqan
+
+#endif // SEQAN_INCLUDE_SEQAN_SIMD_SIMD_BASE_SEQAN_IMPL_AVX512_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
index 8b0bafc..8c4412c 100644
--- a/include/seqan/simd/simd_base_seqan_impl_sse4.2.h
+++ b/include/seqan/simd/simd_base_seqan_impl_sse4.2.h
@@ -157,13 +157,10 @@ _fillVector(TSimdVector & vector,
             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
+    // NOTE(rrahn): For g++-4.9 the set_epi function is a macro, which does not work with parameter pack expansion.
     vector = SEQAN_VECTOR_CAST_(TSimdVector, _mm_set_epi64x(std::get<sizeof...(INDICES) - 1 - INDICES>(args)...));
-#endif
 }
 
 // --------------------------------------------------------------------------
@@ -1035,7 +1032,8 @@ 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);
+    return _mm_testz_si128(SEQAN_VECTOR_CAST_(const __m128i &, vector),
+                           SEQAN_VECTOR_CAST_(const __m128i &, mask));
 }
 
 // --------------------------------------------------------------------------
diff --git a/include/seqan/simd/simd_base_seqan_interface.h b/include/seqan/simd/simd_base_seqan_interface.h
index add88d0..7f2537a 100644
--- a/include/seqan/simd/simd_base_seqan_interface.h
+++ b/include/seqan/simd/simd_base_seqan_interface.h
@@ -42,6 +42,12 @@
 namespace seqan {
 
 template <typename TSimdVector>
+struct SimdMaskVectorImpl<TSimdVector, True>
+{
+    using Type = typename SimdVectorTraits<TSimdVector, SimdParams_<sizeof(TSimdVector), LENGTH<TSimdVector>::VALUE>>::MaskType;
+};
+
+template <typename TSimdVector>
 struct SimdSwizzleVectorImpl<TSimdVector, True>
 {
     typedef typename SimdVector<uint8_t, sizeof(TSimdVector)>::Type Type;
@@ -83,9 +89,9 @@ clearVector(TSimdVector & vector)
 // Function createVector()
 // --------------------------------------------------------------------------
 
-template <typename TSimdVector, typename TValue>
+template <typename TSimdVector>
 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-createVector(TValue const x)
+createVector(typename Value<TSimdVector>::Type const x)
 {
     typedef typename Value<TSimdVector>::Type TIVal;
     return _createVector<TSimdVector>(x, SimdParams_<sizeof(TSimdVector), sizeof(TSimdVector) / sizeof(TIVal)>());
@@ -117,7 +123,7 @@ fillVector(TSimdVector & vector, TValue const... args)
 // --------------------------------------------------------------------------
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 cmpEq (TSimdVector const & a, TSimdVector const & b)
 {
     typedef typename Value<TSimdVector>::Type TValue;
@@ -129,7 +135,7 @@ cmpEq (TSimdVector const & a, TSimdVector const & b)
 // --------------------------------------------------------------------------
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 operator==(TSimdVector const & a, TSimdVector const & b)
 {
     typedef typename Value<TSimdVector>::Type TValue;
@@ -141,7 +147,7 @@ operator==(TSimdVector const & a, TSimdVector const & b)
 // --------------------------------------------------------------------------
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 cmpGt (TSimdVector const & a, TSimdVector const & b)
 {
     typedef typename Value<TSimdVector>::Type TValue;
@@ -153,7 +159,7 @@ cmpGt (TSimdVector const & a, TSimdVector const & b)
 // --------------------------------------------------------------------------
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 operator>(TSimdVector const & a, TSimdVector const & b)
 {
     typedef typename Value<TSimdVector>::Type TValue;
@@ -381,21 +387,6 @@ shuffleVector(TSimdVector1 const & vector, TSimdVector2 const & indices)
                 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
index 4bf54a8..fe4319a 100644
--- a/include/seqan/simd/simd_base_umesimd_impl.h
+++ b/include/seqan/simd/simd_base_umesimd_impl.h
@@ -43,6 +43,12 @@ namespace seqan
 {
 
 template <typename TSimdVector>
+struct SimdMaskVectorImpl<TSimdVector, True>
+{
+    using Type = typename UME::SIMD::SIMDTraits<TSimdVector>::MASK_T;
+};
+
+template <typename TSimdVector>
 struct SimdSwizzleVectorImpl<TSimdVector, True>
 {
     using Type = typename UME::SIMD::SIMDTraits<TSimdVector>::SWIZZLE_T;
@@ -97,6 +103,49 @@ using SimdVector8Int64   = UME::SIMD::SIMDVec<int64_t, 8>;
 using SimdVector8UInt64  = UME::SIMD::SIMDVec<uint64_t, 8>;
 
 // ============================================================================
+// SIMDMaskVector
+// ============================================================================
+
+template <uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDVecMask<LENGTH>),       (SimdMaskVectorConcept));
+
+template <uint32_t LENGTH>
+SEQAN_CONCEPT_IMPL((typename UME::SIMD::SIMDVecMask<LENGTH> const), (SimdMaskVectorConcept));
+
+template <uint32_t LENGTH>
+struct Value<UME::SIMD::SIMDVecMask<LENGTH> >
+{
+    typedef bool Type;
+};
+
+template <uint32_t LENGTH_>
+struct LENGTH<UME::SIMD::SIMDVecMask<LENGTH_> >
+{
+    enum { VALUE = LENGTH_ };
+};
+
+template <uint32_t LENGTH, typename TPosition>
+inline typename Value<UME::SIMD::SIMDVecMask<LENGTH> >::Type
+getValue(UME::SIMD::SIMDVecMask<LENGTH> const & vector, TPosition const pos)
+{
+    return vector[pos];
+}
+
+template <uint32_t LENGTH, typename TPosition>
+inline typename Value<UME::SIMD::SIMDVecMask<LENGTH> >::Type
+value(UME::SIMD::SIMDVecMask<LENGTH> const & vector, TPosition const pos)
+{
+    return vector[pos];
+}
+
+template <uint32_t LENGTH, typename TPosition, typename TValue2>
+inline void
+assignValue(UME::SIMD::SIMDVecMask<LENGTH> &vector, TPosition const pos, TValue2 const value)
+{
+    vector.insert(pos, value);
+}
+
+// ============================================================================
 // SIMDSwizzle
 // ============================================================================
 
@@ -299,14 +348,13 @@ clearVector(TSimdVector & vector)
     vector = 0;
 }
 
-
 // --------------------------------------------------------------------------
 // Function createVector()
 // --------------------------------------------------------------------------
 
-template <typename TSimdVector, typename TValue>
+template <typename TSimdVector>
 inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
-createVector(TValue const x)
+createVector(typename Value<TSimdVector>::Type const x)
 {
     return TSimdVector(x);
 }
@@ -327,13 +375,10 @@ fillVector(TSimdVector & vector, TValue const... args)
 // --------------------------------------------------------------------------
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 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;
+    return a.cmpeq(b);
 }
 
 // --------------------------------------------------------------------------
@@ -341,13 +386,10 @@ cmpEq (TSimdVector const & a, TSimdVector const & b)
 // --------------------------------------------------------------------------
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 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;
+    return a.cmpeq(b);
 }
 
 // --------------------------------------------------------------------------
@@ -355,13 +397,10 @@ operator==(TSimdVector const & a, TSimdVector const & b)
 // --------------------------------------------------------------------------
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 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;
+    return a.cmpgt(b);
 }
 
 // --------------------------------------------------------------------------
@@ -369,13 +408,10 @@ cmpGt (TSimdVector const & a, TSimdVector const & b)
 // --------------------------------------------------------------------------
 
 template <typename TSimdVector>
-inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, TSimdVector)
+inline SEQAN_FUNC_ENABLE_IF(Is<SimdVectorConcept<TSimdVector> >, typename SimdMaskVector<TSimdVector>::Type)
 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;
+    return a.cmpgt(b);
 }
 
 // --------------------------------------------------------------------------
@@ -530,13 +566,7 @@ 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
-    );
+    return a.blend(mask, b);
 }
 
 // --------------------------------------------------------------------------
diff --git a/include/seqan/store/store_all.h b/include/seqan/store/store_all.h
index f44b20d..3dd1d4c 100644
--- a/include/seqan/store/store_all.h
+++ b/include/seqan/store/store_all.h
@@ -1888,13 +1888,13 @@ void convertMatchesToGlobalAlignment(FragmentStore<TSpec, TConfig> &store, TScor
         assignSource(row(align, 1), readSeq);
 //        int ud = store.alignQualityStore[it->id].errors;
 //        int ld = -ud;
-//        if (IsSameType<TShrinkMatches, True>::VALUE)
+//        SEQAN_IF_CONSTEXPR (IsSameType<TShrinkMatches, True>::VALUE)
 //            globalAlignment(align, score, AlignConfig<true, false, false, true>(), ld, ud, Gotoh());
 //        else
 //            globalAlignment(align, score, ld, ud);
 
         int qualValue = 0;
-        if (IsSameType<TShrinkMatches, True>::VALUE)
+        SEQAN_IF_CONSTEXPR (IsSameType<TShrinkMatches, True>::VALUE)
             qualValue = globalAlignment(align, score, AlignConfig<true, false, false, true>(), Gotoh());
         else
             qualValue = globalAlignment(align, score);
diff --git a/include/seqan/store/store_io_sam.h b/include/seqan/store/store_io_sam.h
index e14eab6..96fc236 100644
--- a/include/seqan/store/store_io_sam.h
+++ b/include/seqan/store/store_io_sam.h
@@ -893,7 +893,7 @@ setPrimaryMatch(BamAlignmentRecord & record,
         record.mapQ = 255;
 
 //    // Fill CIGAR using aligned read.
-//    if (!IsSameType<TAlignFunctor, Nothing>::VALUE)
+//    SEQAN_IF_CONSTEXPR (!IsSameType<TAlignFunctor, Nothing>::VALUE)
 //        getCigarString(record.cigar, row(align, 0), row(align, 1));
 
     // Retrieve number of errors from quality store.
diff --git a/include/seqan/stream/file_stream.h b/include/seqan/stream/file_stream.h
index e640086..59f075d 100644
--- a/include/seqan/stream/file_stream.h
+++ b/include/seqan/stream/file_stream.h
@@ -365,7 +365,7 @@ _readFilePage(FilePageTable<TValue, TDirection, TSpec> &, FileMapping<TFileSpec>
     // how to handle pages crossing/beyond the end of file
     if (endOfs > length(file))
     {
-        if (!IsSameType<TDirection, Input>::VALUE)
+        SEQAN_IF_CONSTEXPR (!IsSameType<TDirection, Input>::VALUE)
         {
             // increase file size to next page boundary and map the whole page
             resize(file, endOfs);
@@ -423,7 +423,7 @@ _writeFilePage(FilePageTable<TValue, TDirection, TSpec> & pager, File<TFileSpec>
     typedef typename Size<File<TFileSpec> >::Type TSize;
 
     // only write in write-mode
-    if (IsSameType<TDirection, Input>::VALUE)
+    SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Input>::VALUE)
     {
         page.state = UNUSED;
         return true;    // true = writing completed
@@ -433,7 +433,7 @@ _writeFilePage(FilePageTable<TValue, TDirection, TSpec> & pager, File<TFileSpec>
     page.state = WRITING;
     bool success = asyncWriteAt(file, begin(page.raw, Standard()), length(page.raw), page.filePos, page.request);
 
-    if (!IsSameType<TDirection, Input>::VALUE)
+    SEQAN_IF_CONSTEXPR (!IsSameType<TDirection, Input>::VALUE)
         pager.fileSize = std::max(pager.fileSize, (TSize)page.filePos + (TSize)length(page.raw));
 
     // if an error occurred, throw an I/O exception
@@ -452,7 +452,7 @@ _writeFilePage(FilePageTable<TValue, TDirection, TSpec> & pager, FileMapping<TFi
     page.state = UNUSED;
     unmapFileSegment(file, begin(page.raw, Standard()), capacity(page.raw));
 
-    if (!IsSameType<TDirection, Input>::VALUE)
+    SEQAN_IF_CONSTEXPR (!IsSameType<TDirection, Input>::VALUE)
         pager.fileSize = std::max(pager.fileSize, (TSize)page.filePos + (TSize)length(page.raw));
 
     clear(page.raw);
diff --git a/include/seqan/stream/iter_stream.h b/include/seqan/stream/iter_stream.h
index 6e1e9d7..6814aaa 100644
--- a/include/seqan/stream/iter_stream.h
+++ b/include/seqan/stream/iter_stream.h
@@ -61,7 +61,7 @@ struct StreamIterator {};
 /*!
  * @class StreamBuffer
  * @headerfile <seqan/stream.h>
- * @brief Buffer to use in stream.
+ * @brief Reinterprets the std::basic_streambuf to grant access to protected member functions.
  *
  * @signature template <typename TValue[, typenam TTraits]>
  *            class StreamBuffer : public std::basic_streambuf<TValue, TTraits>;
@@ -69,65 +69,92 @@ struct StreamIterator {};
  * @tparam TValue  The value type of the stream buffer.
  * @tparam TTraits The traits to use, defaults to <tt>std::char_traits<TValue></tt>.
  */
-
 // TODO(holtgrew): Add documentation for member functions.
 
-// Unfortunately some of the most useful members of basic_streambuf are
-// protected, so we define a subclass to cast and access them
-template <typename TValue, typename TTraits_ = std::char_traits<TValue> >
-class StreamBuffer : public std::basic_streambuf<TValue, TTraits_>
+ // Unfortunately some of the most useful members of basic_streambuf are
+ // protected, so we define a subclass to cast and access them
+template <typename TValue, typename TTraits_ = std::char_traits<TValue>>
+struct StreamBuffer : public std::basic_streambuf<TValue, TTraits_>
+{
+    using TTraits      = TTraits_;
+    using TBasicStream = std::basic_streambuf<TValue, TTraits_>;
+
+    using TBasicStream::eback;
+    using TBasicStream::gptr;
+    using TBasicStream::egptr;
+    using TBasicStream::gbump;
+    using TBasicStream::underflow;
+
+    using TBasicStream::pbase;
+    using TBasicStream::pptr;
+    using TBasicStream::epptr;
+    using TBasicStream::pbump;
+    using TBasicStream::overflow;
+};
+
+// NOTE(rrahn): This is a wrapper for the StreamBuffer class.
+// Since we usually work with std::basic_iostreams and their derivatives, we cannot simply cast a pointer to
+// std::basic_filebuf to StreamBuffer to expose it's protected member functions.
+// To do so, we only use the StreamBuffer to inherit from basic_streambuf (the base class of all buffer implementations.)
+// and only expose the protected member functions as public functions. We then store the original basic_streambuf
+// in this wrapper class and whenever access to the protected members is required we use a reinterpret_cast to convert
+// basic_streambuf* into the public StreamBuffer*. The reinterpret_cast has zero overhead.
+// This fixes an undetected error reported w/ the sanitizer option of gcc (https://github.com/seqan/seqan/issues/2104).
+template <typename TValue, typename TTraits_ = std::char_traits<TValue>>
+class StreamBufferWrapper
 {
 public:
-    typedef TTraits_ TTraits;
-    typedef std::basic_streambuf<TValue, TTraits_> TBase;
 
-    using TBase::eback;
-    using TBase::gptr;
-    using TBase::egptr;
+    typedef std::basic_streambuf<TValue, TTraits_> TBasicStreamBuffer;
+    typedef StreamBuffer<TValue, TTraits_>         TPubStreamBuffer_;
+    typedef typename TPubStreamBuffer_::TTraits    TTraits;
 
-    using TBase::pbase;
-    using TBase::pptr;
-    using TBase::epptr;
+    TBasicStreamBuffer * streamBuf{nullptr};
+
+    StreamBufferWrapper() = default;
+
+    explicit StreamBufferWrapper(TBasicStreamBuffer * _basicStreamBuf) : streamBuf(_basicStreamBuf)
+    {}
 
     size_t chunkSize(Input)
     {
-        return egptr() - gptr();
+        return baseBuf()->egptr() - baseBuf()->gptr();
     }
 
     size_t chunkSize(Output)
     {
-        return epptr() - pptr();
+        return baseBuf()->epptr() - baseBuf()->pptr();
     }
 
     template <typename TOffset>
     void advanceChunk(TOffset ofs, Input)
     {
-        this->gbump(ofs);
+        baseBuf()->gbump(ofs);
     }
 
     template <typename TOffset>
     void advanceChunk(TOffset ofs, Output)
     {
-        this->pbump(ofs);
+        baseBuf()->pbump(ofs);
     }
 
     void reserveChunk(Input)
     {
-        if (gptr() == egptr())
-            this->underflow();
+        if (baseBuf()->gptr() == baseBuf()->egptr())
+            baseBuf()->underflow();
     }
 
     void reserveChunk(Output)
     {
-        if (pptr() == epptr())
-            this->overflow(EOF);
+        if (baseBuf()->pptr() == baseBuf()->epptr())
+            baseBuf()->overflow(EOF);
     }
 
     template <typename TOffset>
     typename std::streampos
     seekoff(TOffset ofs, std::ios_base::seekdir way, std::ios_base::openmode which)
     {
-        return TBase::seekoff(ofs, way, which);
+        return streamBuf->pubseekoff(ofs, way, which);
     }
 
     template <typename TOffset, typename TDirection>
@@ -148,10 +175,10 @@ public:
             if (ofs == 0)
                 return;
 
-            if (IsSameType<TDirection, Input>::VALUE)
-                this->underflow();
+            SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Input>::VALUE)
+                baseBuf()->underflow();
             else
-                this->overflow();
+                baseBuf()->overflow();
             left = chunkSize(dir);
 
             if (SEQAN_UNLIKELY(left == 0))
@@ -164,21 +191,26 @@ public:
                 // if seek doesn't work manually skip characters (when reading)
                 if (res == typename TTraits::pos_type(typename TTraits::off_type(-1)))
                 {
-                    if (IsSameType<TDirection, Input>::VALUE)
+                    SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Input>::VALUE)
                     {
                         for (; ofs != 0; --ofs)
-                            this->sbumpc();
+                            baseBuf()->sbumpc();
                     }
-                    if (IsSameType<TDirection, Output>::VALUE)
+                    SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Output>::VALUE)
                     {
                         for (; ofs != 0; --ofs)
-                            this->sputc('\0');
+                            baseBuf()->sputc('\0');
                     }
                 }
                 return;
             }
         }
     }
+
+    TPubStreamBuffer_* baseBuf() const
+    {
+        return reinterpret_cast<TPubStreamBuffer_ *>(streamBuf);
+    }
 };
 
 // ----------------------------------------------------------------------------
@@ -216,12 +248,13 @@ template <typename TStream>
 class Iter<TStream, StreamIterator<Input> >
 {
 public:
-    typedef typename Value<TStream>::Type   TValue;
-    typedef std::basic_istream<TValue>      TIStream;
-    typedef std::basic_streambuf<TValue>    TBasicBuffer;
-    typedef StreamBuffer<TValue>            TStreamBuffer;
+    typedef typename Value<TStream>::Type                    TValue;
+    typedef std::basic_istream<TValue>                       TIStream;
+    typedef std::basic_streambuf<TValue>                     TBasicBuffer;
+    typedef StreamBufferWrapper<TValue>                      TStreamBufferWrapper;
+    typedef typename TStreamBufferWrapper::TPubStreamBuffer_ TStreamBuffer;
 
-    TStreamBuffer *streamBuf;
+    TStreamBufferWrapper streamBufWrapper{nullptr};
 
     /*!
      * @fn InputStreamIterator::Iter
@@ -236,17 +269,15 @@ public:
      *
      * Allows default construction, construction from stream, as well as from a @link StreamBuffer @endlink.
      */
-    Iter() : streamBuf()
-    {}
+    Iter() = default;
 
-    Iter(TIStream & stream) :
-        streamBuf(static_cast<StreamBuffer<TValue> *>(stream.rdbuf()))
+    Iter(TIStream & stream) : streamBufWrapper(stream.rdbuf())
     {
+        // printf("streamBuf: %p\n", streamBuf);
         stream.exceptions(std::ios_base::badbit);
     }
 
-    Iter(TStreamBuffer * buf) :
-        streamBuf(static_cast<StreamBuffer<TValue> *>(buf))
+    Iter(TBasicBuffer * buf) : streamBufWrapper(buf)
     {}
 };
 
@@ -268,12 +299,13 @@ template <typename TStream>
 class Iter<TStream, StreamIterator<Output> >
 {
 public:
-    typedef typename Value<TStream>::Type   TValue;
-    typedef std::basic_ostream<TValue>      TOStream;
-    typedef std::basic_streambuf<TValue>    TBasicBuffer;
-    typedef StreamBuffer<TValue>            TStreamBuffer;
+    typedef typename Value<TStream>::Type                    TValue;
+    typedef std::basic_ostream<TValue>                       TOStream;
+    typedef std::basic_streambuf<TValue>                     TBasicBuffer;
+    typedef StreamBufferWrapper<TValue>                      TStreamBufferWrapper;
+    typedef typename TStreamBufferWrapper::TPubStreamBuffer_ TStreamBuffer;
 
-    TStreamBuffer *streamBuf;
+    TStreamBufferWrapper streamBufWrapper{nullptr};
 
     /*!
      * @fn Iter::Iter
@@ -288,17 +320,14 @@ public:
      *
      * Allows default construction, construction from stream, as well as from a @link StreamBuffer @endlink.
      */
-    Iter() : streamBuf()
-    {}
+    Iter() = default;
 
-    Iter(TOStream & stream):
-        streamBuf(static_cast<StreamBuffer<TValue> *>(stream.rdbuf()))
+    Iter(TOStream & stream) : streamBufWrapper(stream.rdbuf())
     {
         stream.exceptions(std::ios_base::badbit);
     }
 
-    Iter(TBasicBuffer *buf):
-        streamBuf(static_cast<StreamBuffer<TValue> *>(buf))
+    Iter(TBasicBuffer * buf) : streamBufWrapper(buf)
     {}
 
     template <typename TValue2>
@@ -505,13 +534,13 @@ directionIterator(TContainer &cont, TDirection const &)
 template <typename TStream, typename TDirection, typename TSize>
 inline void reserveChunk(Iter<TStream, StreamIterator<TDirection> > &iter, TSize, Input dir)
 {
-    iter.streamBuf->reserveChunk(dir);
+    iter.streamBufWrapper.reserveChunk(dir);
 }
 
 template <typename TStream, typename TDirection, typename TSize>
 inline void reserveChunk(Iter<TStream, StreamIterator<TDirection> > &iter, TSize, Output dir)
 {
-    iter.streamBuf->reserveChunk(dir);
+    iter.streamBufWrapper.reserveChunk(dir);
 }
 
 // ----------------------------------------------------------------------------
@@ -523,7 +552,7 @@ inline void reserveChunk(Iter<TStream, StreamIterator<TDirection> > &iter, TSize
 template <typename TStream, typename TDirection, typename TSize>
 inline void advanceChunk(Iter<TStream, StreamIterator<TDirection> > &iter, TSize size)
 {
-    iter.streamBuf->advanceChunk(size, TDirection());
+    iter.streamBufWrapper.advanceChunk(size, TDirection());
 }
 
 // ----------------------------------------------------------------------------
@@ -550,8 +579,8 @@ template <typename TChunk, typename TStream, typename TDirection>
 inline void
 getChunk(TChunk &result, Iter<TStream, StreamIterator<Tag<TDirection> > > &iter, Tag<TDirection>)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    getChunk(result, *iter.streamBuf, Tag<TDirection>());
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    getChunk(result, *iter.streamBufWrapper.baseBuf(), Tag<TDirection>());
 }
 
 // ----------------------------------------------------------------------------
@@ -562,15 +591,15 @@ template <typename TStream>
 inline typename Reference<Iter<TStream, StreamIterator<Input> > >::Type
 value(Iter<TStream, StreamIterator<Input> > &iter)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    return iter.streamBuf->sgetc();
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    return iter.streamBufWrapper.baseBuf()->sgetc();
 }
 template <typename TStream>
 inline typename Reference<Iter<TStream, StreamIterator<Input> > const>::Type
 value(Iter<TStream, StreamIterator<Input> > const &iter)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    return iter.streamBuf->sgetc();
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    return iter.streamBufWrapper.baseBuf()->sgetc();
 }
 
 // ----------------------------------------------------------------------------
@@ -600,12 +629,13 @@ setValue(Iter<TStream, StreamIterator<Output> > & iter, TValue const &val)
 {
     return setValue(const_cast<Iter<TStream, StreamIterator<Output> > const &>(iter), val);
 }
+
 template <typename TStream, typename TValue>
 inline void
 setValue(Iter<TStream, StreamIterator<Output> > const & iter, TValue const &val)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    iter.streamBuf->sputc((typename Value<Iter<TStream, StreamIterator<Output> > >::Type)val);
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    iter.streamBufWrapper.baseBuf()->sputc((typename Value<Iter<TStream, StreamIterator<Output> > >::Type)val);
 }
 
 // ----------------------------------------------------------------------------
@@ -628,8 +658,8 @@ template <typename TStream>
 inline void
 goNext(Iter<TStream, StreamIterator<Input> > & iter)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    iter.streamBuf->sbumpc();
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    iter.streamBufWrapper.baseBuf()->sbumpc();
 }
 
 template <typename TStream>
@@ -646,8 +676,8 @@ template <typename TContainer, typename TSpec>
 inline void
 operator++(Iter<TContainer, StreamIterator<Input> > & iter, int)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    iter.streamBuf->sbumpc();
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    iter.streamBufWrapper.baseBuf()->sbumpc();
 }
 
 // ----------------------------------------------------------------------------
@@ -658,8 +688,8 @@ template <typename TStream, typename TOffset, typename TDirection>
 inline void
 goFurther(Iter<TStream, StreamIterator<TDirection> > &iter, TOffset ofs)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    iter.streamBuf->goFurther(ofs, TDirection());
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    iter.streamBufWrapper.goFurther(ofs, TDirection());
 }
 
 // ----------------------------------------------------------------------------
@@ -670,8 +700,8 @@ template <typename TStream, typename TDirection>
 inline typename Position<Iter<TStream, StreamIterator<TDirection> > const>::Type
 position(Iter<TStream, StreamIterator<TDirection> > const & iter)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    return iter.streamBuf->pubseekoff(0, std::ios_base::cur,
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    return iter.streamBufWrapper.baseBuf()->pubseekoff(0, std::ios_base::cur,
                                       (IsSameType<TDirection, Input>::VALUE)? std::ios_base::in: std::ios_base::out);
 }
 
@@ -683,8 +713,8 @@ template <typename TStream, typename TDirection, typename TPosition>
 inline void
 setPosition(Iter<TStream, StreamIterator<TDirection> > const & iter, TPosition pos)
 {
-    SEQAN_ASSERT(iter.streamBuf != NULL);
-    iter.streamBuf->pubseekpos(pos, (IsSameType<TDirection, Input>::VALUE)? std::ios_base::in: std::ios_base::out);
+    SEQAN_ASSERT(iter.streamBufWrapper.baseBuf() != nullptr);
+    iter.streamBufWrapper.baseBuf()->pubseekpos(pos, (IsSameType<TDirection, Input>::VALUE)? std::ios_base::in: std::ios_base::out);
 }
 
 // ----------------------------------------------------------------------------
@@ -698,13 +728,13 @@ atEnd(Iter<TStream, StreamIterator<Input> > const & iter)
     typedef typename Value<Iter<TStream, StreamIterator<Input> > >::Type TValue;
     typedef StreamBuffer<TValue> TStreamBuffer;
 
-    if (SEQAN_UNLIKELY(iter.streamBuf == NULL))
+    if (SEQAN_UNLIKELY(iter.streamBufWrapper.baseBuf() == nullptr))
     {
         return true;
     }
     else
     {
-        TStreamBuffer *buf = static_cast<TStreamBuffer*>(iter.streamBuf);
+        TStreamBuffer * const buf = iter.streamBufWrapper.baseBuf();
         if (SEQAN_LIKELY(buf->gptr() < buf->egptr()))
             return false;
         else
@@ -719,13 +749,13 @@ atEnd(Iter<TStream, StreamIterator<Output> > const & iter)
     typedef typename Value<Iter<TStream, StreamIterator<Input> > >::Type TValue;
     typedef StreamBuffer<TValue> TStreamBuffer;
 
-    if (SEQAN_UNLIKELY(iter.streamBuf == NULL))
+    if (SEQAN_UNLIKELY(iter.streamBufWrapper.baseBuf() == nullptr))
     {
         return true;
     }
     else
     {
-        TStreamBuffer *buf = static_cast<TStreamBuffer*>(iter.streamBuf);
+        TStreamBuffer * const buf = iter.streamBufWrapper.baseBuf();
         if (SEQAN_LIKELY(buf->pptr() < buf->epptr()))
             return false;
         else
diff --git a/include/seqan/stream/virtual_stream.h b/include/seqan/stream/virtual_stream.h
index 64b21ec..26f3c23 100644
--- a/include/seqan/stream/virtual_stream.h
+++ b/include/seqan/stream/virtual_stream.h
@@ -557,15 +557,16 @@ open(VirtualStream<TValue, TDirection, TTraits> &stream, TStream &fileStream, TC
     typedef typename TVirtualStream::TBufferedStream TBufferedStream;
 
     // peek the first character to initialize the underlying streambuf (for in_avail)
-    if (IsSameType<TDirection, Input>::VALUE)  // Only getc if input stream.
+    SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Input>::VALUE)  // Only getc if input stream.
         fileStream.rdbuf()->sgetc();
 
-    if (IsSameType<TDirection, Input>::VALUE &&
-        !IsSameType<TStream, TBufferedStream>::VALUE &&
-        fileStream.rdbuf()->in_avail() < 2)
+    SEQAN_IF_CONSTEXPR (IsSameType<TDirection, Input>::VALUE && !IsSameType<TStream, TBufferedStream>::VALUE)
     {
-        stream.bufferedStream.setStream(fileStream);
-        return open(stream, stream.bufferedStream, compressionType);
+        if (fileStream.rdbuf()->in_avail() < 2)
+        {
+            stream.bufferedStream.setStream(fileStream);
+            return open(stream, stream.bufferedStream, compressionType);
+        }
     }
 
     VirtualStreamFactoryContext_<TVirtualStream> ctx(fileStream);
diff --git a/include/seqan/translation/translation.h b/include/seqan/translation/translation.h
index 01dd0c3..15f6794 100644
--- a/include/seqan/translation/translation.h
+++ b/include/seqan/translation/translation.h
@@ -312,8 +312,8 @@ _translateImplLoopOMPWrapper(TTarget & target,
 {
     SEQAN_OMP_PRAGMA(parallel for schedule(dynamic))
     for (int64_t i = 0; i < static_cast<int64_t>(length(target)); ++i)
-        _translateImplLoop(target, i, source, GeneticCode<CODE_SPEC>(),
-                           Frames_<frames>());
+        if (length(source[i/frames]) >= 3) // make sure there is enough to translate
+            _translateImplLoop(target, i, source, GeneticCode<CODE_SPEC>(), Frames_<frames>());
 }
 
 template <typename TSource, typename TTarget, uint8_t frames,
@@ -327,8 +327,8 @@ _translateImplLoopOMPWrapper(TTarget & target,
 {
     typedef typename Size<TTarget>::Type TPos;
     for (TPos i = 0; i < length(target); ++i)
-        _translateImplLoop(target, i, source, GeneticCode<CODE_SPEC>(),
-                           Frames_<frames>());
+        if (length(source[i/frames]) >= 3) // make sure there is enough to translate
+            _translateImplLoop(target, i, source, GeneticCode<CODE_SPEC>(), Frames_<frames>());
 }
 
 // --------------------------------------------------------------------------
@@ -353,7 +353,7 @@ _translateImpl(StringSet<String<AminoAcid, TSpec1>, TSpec2> & target,
         // current dnastring's length / 3 (3DNA -> 1 AA)
         TPos len = length(source[i/n]) / 3;
         // shorten for shifted frames
-        if (( n > 2 ) && ( length(source[i/n]) % 3 ) < ( i%3 ))
+        if ((len > 0) && ( n > 2 ) && ((length(source[i/n]) % 3) < (i % 3)))
             --len;
         resize(target[i], len, Exact());
     }
@@ -383,7 +383,7 @@ _translateImpl(StringSet<String<AminoAcid,
         // current dnastring's length / 3 (3DNA -> 1 AA)
         TPos len = length(source[i/n]) / 3;
         // shorten for shifted frames
-        if (( n > 2 ) && ( length(source[i/n]) % 3 ) < ( i%3 ))
+        if ((len > 0) && ( n > 2 ) && ( length(source[i/n]) % 3 ) < ( i%3 ))
             --len;
         target.limits[i+1] = target.limits[i] + len;
     }
diff --git a/include/seqan/vcf_io/read_vcf.h b/include/seqan/vcf_io/read_vcf.h
index 0d3305a..80b4a42 100644
--- a/include/seqan/vcf_io/read_vcf.h
+++ b/include/seqan/vcf_io/read_vcf.h
@@ -144,12 +144,16 @@ readHeader(VcfHeader & header,
             // Split line, get sample names.
             StringSet<CharString> fields;
             strSplit(fields, buffer, IsTab());
-            if (length(fields) < 9u)
+            if (length(fields) < 8u)
                 SEQAN_THROW(ParseError("Not enough fields."));
 
             // Get sample names.
-            for (unsigned i = 9; i < length(fields); ++i)
+            for (unsigned i = 8; i < length(fields); ++i)
+            {
+                if(i == 8 && fields[i] == "FORMAT")
+                    continue;
                 appendName(sampleNamesCache(context), fields[i]);
+            }
         }
     }
 }
@@ -166,109 +170,51 @@ readRecord(VcfRecord & record,
            TForwardIter & iter,
            Vcf const & /*tag*/)
 {
-    typedef OrFunctor<IsTab, AssertFunctor<NotFunctor<IsNewline>, ParseError, Vcf> > NextEntry;
-
     clear(record);
     CharString &buffer = context.buffer;
 
-    // CHROM
+    // get the next line on the buffer.
     clear(buffer);
-    readUntil(buffer, iter, NextEntry());
-    if (empty(buffer))
-        SEQAN_THROW(EmptyFieldError("CHROM"));
-    record.rID = nameToId(contigNamesCache(context), buffer);
-    skipOne(iter);
 
-    // POS
-    clear(buffer);
-    readUntil(buffer, iter, NextEntry());
-    if (empty(buffer))
-        SEQAN_THROW(EmptyFieldError("POS"));
-    record.beginPos = lexicalCast<int32_t>(buffer) - 1; // Translate from 1-based to 0-based.
-    skipOne(iter);
-
-    // ID
-    readUntil(record.id, iter, NextEntry());
-    if (empty(record.id))
-        SEQAN_THROW(EmptyFieldError("ID"));
-    skipOne(iter);
-
-    // REF
-    readUntil(record.ref, iter, NextEntry());
-    if (empty(record.id))
-        SEQAN_THROW(EmptyFieldError("REF"));
-    skipOne(iter);
-
-    // ALT
-    readUntil(record.alt, iter, NextEntry());
-    if (empty(record.id))
-        SEQAN_THROW(EmptyFieldError("ALT"));
-    skipOne(iter);
-
-    // QUAL
-    clear(buffer);
-    readUntil(buffer, iter, NextEntry());
-    if (empty(buffer))
-        SEQAN_THROW(EmptyFieldError("QUAL"));
+    readLine(buffer, iter);
+    // Split line, get field and sample values.
+    // The first 8(9) columns are fields and the rest are values for samples
+    //"#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT")
+    StringSet<CharString> field_values;
+    strSplit(field_values, buffer, IsTab(), false);
 
-    if (buffer == ".")
-        record.qual = VcfRecord::MISSING_QUAL();
-    else
-        lexicalCastWithException(record.qual, buffer);
+    unsigned numSamples = length(sampleNames(context));
+
+    if (length(field_values) < 8u + numSamples)
+        SEQAN_THROW(ParseError("Not enough values in a line."));
 
-    skipOne(iter);
+    record.rID      = nameToId(contigNamesCache(context), field_values[0]);
+    record.beginPos = lexicalCast<int32_t>(field_values[1]) - 1; // Translate from 1-based to 0-based.
+    record.id       = field_values[2];
+    record.ref      = field_values[3];
+    record.alt      = field_values[4];
 
-    // FILTER
-    readUntil(record.filter, iter, NextEntry());
-    if (empty(record.filter))
-        SEQAN_THROW(EmptyFieldError("FILTER"));
-    skipOne(iter);
+    if (field_values[5] == ".")
+        record.qual = VcfRecord::MISSING_QUAL();
+    else
+        lexicalCastWithException(record.qual, field_values[5]);
 
-    // INFO
-    readUntil(record.info, iter, OrFunctor<IsTab, IsNewline>());
-    if (empty(record.info))
-        SEQAN_THROW(EmptyFieldError("INFO"));
+    record.filter   = field_values[6];
+    record.info     = field_values[7];
 
-    // the following columns are optional
-    if (atEnd(iter) || IsNewline()(value(iter)))
+    //check if we have a spare column for FORMAT
+    unsigned samplesColStart = 8;
+    if (length(field_values) > 8u + numSamples) // we have extara column for FORMAT
     {
-        skipLine(iter);
-        return;
+        record.format = field_values[8];
+        samplesColStart = 9;
     }
-    skipOne(iter);
-
-    // FORMAT
-    readUntil(record.format, iter, NextEntry());
-    if (empty(record.format))
-        SEQAN_THROW(EmptyFieldError("FORMAT"));
-    skipOne(iter);
 
-    // The samples.
-    unsigned numSamples = length(sampleNames(context));
-    for (unsigned i = 0; i < numSamples; ++i)
+    // Get sample name values .
+    for (unsigned i = samplesColStart; i < length(field_values); ++i)
     {
-        clear(buffer);
-        if (i + 1 != numSamples)
-        {
-            readUntil(buffer, iter, NextEntry());
-            skipOne(iter);
-        }
-        else
-        {
-            readUntil(buffer, iter, OrFunctor<IsTab, IsNewline>());
-        }
-
-        if (empty(buffer))
-        {
-            char buffer[30];    // == 9 (GENOTYPE_) + 20 (#digits in MIN_INT64) + 1 (trailing zero)
-            snprintf(buffer, 30, "GENOTYPE_%u", i + 1);
-            SEQAN_THROW(EmptyFieldError(buffer));
-        }
-        appendValue(record.genotypeInfos, buffer);
+        appendValue(record.genotypeInfos, field_values[i]);
     }
-
-    // skip line break and optional additional columns
-    skipLine(iter);
 }
 
 }  // namespace seqan
diff --git a/manual/source/Infrastructure/Use/Install.rst b/manual/source/Infrastructure/Use/Install.rst
index 85dadac..e3ce7d4 100644
--- a/manual/source/Infrastructure/Use/Install.rst
+++ b/manual/source/Infrastructure/Use/Install.rst
@@ -32,27 +32,27 @@ SeqAn is available natively on the following platforms.
     
     <br/>
 
-+---------------------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| Operating System          | Package Name       | Command                                      | links                                                                                                                                                        |
-+============+==============+====================+==============================================+==============================================================================================================================================================+
-| **G** |br| | Arch         |                    |                                              | `AUR <https://aur.archlinux.org/packages/?O=0&K=seqan>`__                                                                                                    |
-| **N** |br| +--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| **U** |br| | Debian       | libseqan2-dev      | ``apt install libseqan2-dev``                | `info <https://packages.debian.org/search?keywords=libseqan2-dev>`__ | `contact <mailto:debian-med-packaging()lists.alioth.debian.org>`__                    |
-| / |br|     +--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| **L** |br| | Fedora       | seqan-devel        | ``yum install seqan-devel``                  | `info <https://apps.fedoraproject.org/packages/seqan-devel>`__ | `contact <mailto:sagitter()fedoraproject.org>`__                                            |
-| **I** |br| +--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| **N** |br| | Gentoo       | seqan              | ``emerge sci-biology/seqan``                 | `info <https://packages.gentoo.org/packages/sci-biology/seqan>`__ | `contact <mailto:sci-biology at gentoo.org>`__                                              |
-| **U** |br| +--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| **X** |br| | Ubuntu       | seqan-dev          | ``apt install seqan-dev``                    | `info <http://packages.ubuntu.com/xenial/seqan-dev>`__ | `contact <mailto:ubuntu-motu()lists.ubuntu.com>`__                                                  |
-+------------+--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| **M** |br| | Homebrew     | seqan              | ``brew install homebrew/science/seqan``      | `info <http://braumeister.org/repos/Homebrew/homebrew-science/formula/seqan>`__ | `contact <mailto:tim()tim-smith.us>`__                                     |
-| **A** |br| +--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| **C** |br| | MacPorts     | seqan              | ``port install seqan``                       | `info <https://trac.macports.org/browser/trunk/dports/science/seqan/Portfile>`__ | `contact <mailto:rene.rahn()fu-berlin.de>`__                              |
-+------------+--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| **B** |br| | FreeBSD      | seqan              | ``pkg install seqan``                        | `info <http://freshports.org/biology/seqan>`__ | `contact <mailto:h2+fbsdports()fsfe.org>`__                                                                 |
-| **S** |br| +--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| **D** |br| | OpenBSD      | seqan              | ``pkg_add seqan``                            | `info <http://openports.se/biology/seqan>`__ | `contact <mailto:h2+fbsdports()fsfe.org>`__                                                                   |
-+------------+--------------+--------------------+----------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
++-------------------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Operating System        | Package Name   | Command                                 | links                                                                                                                                                                  |
++============+============+================+=========================================+========================================================================================================================================================================+
+| **G** |br| | Arch       | seqan (AUR)    |  *depends*                              | `info <https://aur.archlinux.org/packages/seqan/>`__                                                                                                                   |
+| **N** |br| +------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **U** |br| | Debian     | libseqan2-dev  | ``apt install libseqan2-dev``           | `info <https://packages.debian.org/search?keywords=libseqan2-dev>`__ | `contact <mailto:debian-med-packaging()lists.alioth.debian.org>`__                              |
+| / |br|     +------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **L** |br| | Fedora     | seqan-devel    | ``yum install seqan-devel``             | `info <https://apps.fedoraproject.org/packages/seqan-devel>`__ | `contact <mailto:sagitter()fedoraproject.org>`__                                                      |
+| **I** |br| +------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **N** |br| | Gentoo     | seqan          | ``emerge sci-biology/seqan``            | `info <https://packages.gentoo.org/packages/sci-biology/seqan>`__ | `contact <mailto:sci-biology at gentoo.org>`__                                                        |
+| **U** |br| +------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **X** |br| | Ubuntu     | libseqan2-dev  | ``apt install libseqan2-dev``           | `info <https://packages.ubuntu.com/search?keywords=libseqan2-dev&searchon=names&suite=all&section=all>`__ | `contact <mailto:ubuntu-devel-discuss at lists.ubuntu.com>`__ |
++------------+------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **M** |br| | Homebrew   | seqan          | ``brew install homebrew/science/seqan`` | `info <http://braumeister.org/repos/Homebrew/homebrew-science/formula/seqan>`__ | `contact <mailto:tim()tim-smith.us>`__                                               |
+| **A** |br| +------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **C** |br| | MacPorts   | seqan          | ``port install seqan``                  | `info <https://trac.macports.org/browser/trunk/dports/science/seqan/Portfile>`__ | `contact <mailto:rene.rahn()fu-berlin.de>`__                                        |
++------------+------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **B** |br| | FreeBSD    | seqan          | ``pkg install seqan``                   | `info <http://freshports.org/biology/seqan>`__ | `contact <mailto:h2+fbsdports()fsfe.org>`__                                                                           |
+| **S** |br| +------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **D** |br| | OpenBSD    | seqan          | ``pkg_add seqan``                       | `info <http://openports.se/biology/seqan>`__ | `contact <mailto:h2+fbsdports()fsfe.org>`__                                                                             |
++------------+------------+----------------+-----------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 
 You should execute the above commands in a terminal as the ``root`` user or prefix them with ``sudo``. If you have problems installing the package on your operating system, or it is outdated, please write to the contact shown above (and replace ``()`` in the e-mail-address with ``@``).
 
diff --git a/manual/source/Tutorial/Algorithms/PatternMatching/OptimalSearchSchemes.rst b/manual/source/Tutorial/Algorithms/PatternMatching/OptimalSearchSchemes.rst
new file mode 100644
index 0000000..3bbf82f
--- /dev/null
+++ b/manual/source/Tutorial/Algorithms/PatternMatching/OptimalSearchSchemes.rst
@@ -0,0 +1,72 @@
+.. sidebar:: ToC
+
+    .. contents::
+
+.. _tutorial-algorithms-optimal-search-schemes:
+
+Optimal Search Schemes
+======================
+
+Learning Objective
+  In this tutorial you will learn how to search a known pattern in a string or :dox:`StringSet` using a bidirectional index.
+  The implemented algorithm in SeqAn is based on Optimal Search Schemes from the `FAMOUS paper <https://arxiv.org/abs/1711.02035>`_ which allows for searching for up to 4 errors based on Hamming distance or Edit distance.
+
+Difficulty
+  Average
+
+Duration
+  15 min
+
+Prerequisites
+  :ref:`tutorial-datastructures-sequences`, :ref:`tutorial-datastructures-indices`
+
+Overview
+--------
+
+Searching in an index with more than two errors is computationally very expensive and thus trivial approaches such as simple backtracking are not recommended.
+Optimal Search Schemes make use of a bidirectional index, split the pattern to be searched into multiple pieces and enumerate it in a more efficient fashion.
+To use this algorithm, you can simply call the ``find()`` method.
+
+.. includefrags:: demos/tutorial/indices/find2_index_approx.cpp
+      :fragment: SinglePattern
+
+The first argument is the delegate function that will be called if a match of the pattern is found.
+It gets an iterator of the bidirectional index and you can choose how to proceed with the hits.
+Additionally it passes a reference to the original pattern searched as well as the number of errors for the current hit in the index.
+
+.. includefrags:: demos/tutorial/indices/find2_index_approx.cpp
+      :fragment: Delegate
+
+The second argument has to be a bidirectional index, currently SeqAn offers only bidirectional FM indices.
+(Please check the corresponding tutorial on :ref:`tutorial-datastructures-indices-fm-index` for more information how FM indices can be configured and constructed.)
+
+The third argument is a :dox:`String` that you want to search.
+
+The number of allowed errors (lower and upper bounds) are passed as template arguments.
+Please note that these parameters have to be ``constexpr``.
+The distance metric is passed as fourth argument. You can choose between ``HammingDistance()`` and ```EditDistance()`` (also known as Levenshtein distance).
+
+You also have to possibility to pass a :dox:`StringSet` of patterns to search instead of a single :dox:`String`.
+The search can then be parallized by passing a fifth parameter tag ``Parallel()`` instead of ``Serial()``.
+
+.. includefrags:: demos/tutorial/indices/find2_index_approx.cpp
+      :fragment: MultiplePatterns
+
+.. warning::
+
+      Please be aware that the same hits might be reported multiple times and you might have to filter these duplicated depending on your application, especially with larger errors numbers.
+
+.. note::
+
+      When searching a StringSet in parallel mode the delegate is likely being executed by different threads at the same time.
+      You have to take care by yourself that the threads do not interfere, e.g. write not into a variable simultaneously.
+      One way of achieving this is by using lock guards.
+      The following example buffers all hits in a set (to filter duplicates) and prints them afterwards.
+
+      .. includefrags:: demos/tutorial/indices/find2_index_approx.cpp
+            :fragment: ParallelMode
+
+Here is a complete example for searching a string or a stringset (in serial mode):
+
+.. includefrags:: demos/tutorial/indices/find2_index_approx.cpp
+      :fragment: Complete
diff --git a/manual/source/Tutorial/Algorithms/PatternMatching/index.rst b/manual/source/Tutorial/Algorithms/PatternMatching/index.rst
index 4d3a8e2..3bf752e 100644
--- a/manual/source/Tutorial/Algorithms/PatternMatching/index.rst
+++ b/manual/source/Tutorial/Algorithms/PatternMatching/index.rst
@@ -9,6 +9,7 @@ Pattern Matching
 
     OnlinePatternMatching
     IndexedPatternMatching
+    OptimalSearchSchemes
 
 Pattern matching is about searching a known string or :dox:`StringSet` (``needle``) in another string or :dox:`StringSet` (``haystack``).
 This tutorial will introduce you into the SeqAn classes :dox:`Finder` and :dox:`Pattern`.
@@ -34,3 +35,4 @@ The :dox:`Pattern` can be asked for the number of the found sequence if the ``ne
 Subsequent calls of find can be used to find more occurrences of the ``needle``, until no more occurrences can be found and find returns ``false``.
 
 In general, search algorithms can be divided into algorithms that preprocess the ``needle`` (online search) or preprocess the ``haystack`` (index search).
+The additional section on Optimal Search Schemes is also an indexed search algorithm but due to a different interface separated into its own section.
diff --git a/manual/source/Tutorial/GettingStarted/AFirstExample.rst b/manual/source/Tutorial/GettingStarted/AFirstExample.rst
index aad59cf..30f1004 100644
--- a/manual/source/Tutorial/GettingStarted/AFirstExample.rst
+++ b/manual/source/Tutorial/GettingStarted/AFirstExample.rst
@@ -377,6 +377,7 @@ In addition, because they are so frequently used there are shortcuts as well.
 For example :dox:`Blosum62` is really a **shortcut** for ``Score<int, ScoreMatrix<AminoAcid, Blosum62_> >``, which is obviously very helpful.
 Other shortcuts are ``DnaString`` for ``String<Dna>`` (:ref:`sequence tutorial <tutorial-datastructures-sequences>`), ``CharString`` for ``String<char>``, ...
 
+.. _template-subclassing:
 .. tip::
 
    Template Subclassing
diff --git a/manual/source/Tutorial/GettingStarted/BackgroundAndMotivation.rst b/manual/source/Tutorial/GettingStarted/BackgroundAndMotivation.rst
index 13e3ea4..55d08a4 100644
--- a/manual/source/Tutorial/GettingStarted/BackgroundAndMotivation.rst
+++ b/manual/source/Tutorial/GettingStarted/BackgroundAndMotivation.rst
@@ -135,11 +135,11 @@ With the words of the C++ inventor `Bjarne Stroustrup <http://www.artima.com/int
 OOP vs. Generic Programming
 ---------------------------
 
-In SeqAn, we use a technique called `template subclassing <tutorial-getting-started-template-subclassing>`_ which is based on generic programming.
+In SeqAn, we use a technique called :ref:`template subclassing <template-subclassing>` which is based on generic programming.
 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 :ref:`the section "From OOP to SeqAn" in the First Steps Tutorial <oop-to-seqan>`.
+An example will be given in :ref:`the section "From OOP to SeqAn" in the First Example Tutorial <oop-to-seqan>`.
 
 .. todo::
     We need a little code example here.
diff --git a/tests/align/CMakeLists.txt b/tests/align/CMakeLists.txt
index b65f2db..e3dc3ec 100644
--- a/tests/align/CMakeLists.txt
+++ b/tests/align/CMakeLists.txt
@@ -12,9 +12,10 @@ message (STATUS "Configuring tests/align")
 
 set (ALIGN_SIMD_TEST TRUE CACHE INTERNAL "Whether to build test_align_simd.")
 # workaround a bug in llvm35 on FreeBSD
-if ((${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") AND
+if ((SEQAN_TRAVIS_BUILD) OR
+    ((${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") AND
     (COMPILER_CLANG) AND
-    (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6.0))
+    (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6.0)))
     set (ALIGN_SIMD_TEST FALSE CACHE INTERNAL "Whether to build test_align_simd.")
 endif ()
 
@@ -66,17 +67,43 @@ target_link_libraries (test_align ${SEQAN_LIBRARIES})
 
 if (ALIGN_SIMD_TEST)
     # Add executable for simd tests.
-    add_executable (test_align_simd
-                    test_align_simd.cpp
-                    test_align_simd.h)
+    add_executable (test_align_simd_global_equal_length
+                    test_align_simd_global_equal_length.cpp
+                    test_align_simd_base.h
+                    test_align_simd_global.h
+                    test_mock.h)
+
+    add_executable (test_align_simd_global_variable_length
+                    test_align_simd_global_variable_length.cpp
+                    test_align_simd_base.h
+                    test_align_simd_global.h
+                    test_mock.h)
+
+    add_executable (test_align_simd_local_equal_length
+                    test_align_simd_local_equal_length.cpp
+                    test_align_simd_base.h
+                    test_align_simd_local.h
+                    test_mock.h)
+
+    add_executable (test_align_simd_local_variable_length
+                    test_align_simd_local_variable_length.cpp
+                    test_align_simd_base.h
+                    test_align_simd_local.h
+                    test_mock.h)
 
     # Add dependencies found by find_package (SeqAn).
-    target_link_libraries (test_align_simd ${SEQAN_LIBRARIES})
+    target_link_libraries (test_align_simd_global_equal_length ${SEQAN_LIBRARIES})
+    target_link_libraries (test_align_simd_global_variable_length ${SEQAN_LIBRARIES})
+    target_link_libraries (test_align_simd_local_equal_length ${SEQAN_LIBRARIES})
+    target_link_libraries (test_align_simd_local_variable_length ${SEQAN_LIBRARIES})
     # note(marehr): there is a bug when using <=clang3.8 with gcc4.9's stdlib,
     # where the default -ftemplate-depth=256 of clang is insufficient.
     # test_align_simd_avx2 needs a depth of at least 266.
     if (COMPILER_CLANG)
-      target_compile_options(test_align_simd PRIVATE -ftemplate-depth=1024)
+      target_compile_options(test_align_simd_global_equal_length PRIVATE -ftemplate-depth=1024)
+      target_compile_options(test_align_simd_global_variable_length PRIVATE -ftemplate-depth=1024)
+      target_compile_options(test_align_simd_local_equal_length PRIVATE -ftemplate-depth=1024)
+      target_compile_options(test_align_simd_local_variable_length PRIVATE -ftemplate-depth=1024)
     endif()
 endif()
 
@@ -90,5 +117,8 @@ 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)
     include (SeqAnSimdUtility)
-    add_simd_platform_tests(test_align_simd)
+    add_simd_platform_tests(test_align_simd_global_equal_length)
+    add_simd_platform_tests(test_align_simd_global_variable_length)
+    add_simd_platform_tests(test_align_simd_local_equal_length)
+    add_simd_platform_tests(test_align_simd_local_variable_length)
 endif ()
diff --git a/tests/align/test_align.cpp b/tests/align/test_align.cpp
index 762f45b..60f403d 100644
--- a/tests/align/test_align.cpp
+++ b/tests/align/test_align.cpp
@@ -189,9 +189,9 @@ SEQAN_BEGIN_TESTSUITE(test_align)
     // Test DPCell.
     // ----------------------------------------------------------------------------
 
-	SEQAN_CALL_TEST(test_dp_cell_value);
-	SEQAN_CALL_TEST(test_dp_cell_reference);
-	SEQAN_CALL_TEST(test_dp_cell_default_infinity);
+    SEQAN_CALL_TEST(test_dp_cell_value);
+    SEQAN_CALL_TEST(test_dp_cell_reference);
+    SEQAN_CALL_TEST(test_dp_cell_default_infinity);
 
     SEQAN_CALL_TEST(test_dp_cell_linear_constructor);
     SEQAN_CALL_TEST(test_dp_cell_linear_copy_constructor);
@@ -274,31 +274,24 @@ SEQAN_BEGIN_TESTSUITE(test_align)
     // Test DPMatrix Navigator.
     // ----------------------------------------------------------------------------
 
-    SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_constructor);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_init_unbanded);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_init_banded);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_go_next_cell);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_assign_value);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_value);
-    SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_previous_cell_diagonal);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_previous_cell_horizontal);
-    SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_previous_cell_vertical);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_coordinate);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_container);
 
-    SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_constructor);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_init_unbanded);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_init_banded);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_go_next);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_assign_value);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_value);
-    SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_previous_cell_diagonal);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_previous_cell_horizontal);
-    SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_previous_cell_vertical);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_coordinate);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_container);
 
-    SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_trace_matrix_constructor);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_init_unbanded);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_trace_matrix_disabled_init_unbanded);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_init_banded);
@@ -308,6 +301,7 @@ SEQAN_BEGIN_TESTSUITE(test_align)
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_value);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_coordinate);
     SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_container);
+    SEQAN_CALL_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_to_global_position);
 
     // ----------------------------------------------------------------------------
     // Test Recursion Formula.
diff --git a/tests/align/test_align_simd.h b/tests/align/test_align_simd.h
deleted file mode 100644
index dff2770..0000000
--- a/tests/align/test_align_simd.h
+++ /dev/null
@@ -1,559 +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: Rene Rahn <rene.rahn at fu-berlin.de>
-// ==========================================================================
-
-#ifndef TESTS_ALIGN_TEST_ALIGN_SIMD_H_
-#define TESTS_ALIGN_TEST_ALIGN_SIMD_H_
-
-#include <tuple>
-
-#include <seqan/basic.h>
-#include <seqan/align.h>
-
-namespace impl
-{
-namespace test_align_simd
-{
-
-struct TestAlignSimdVariableLength_;
-using VariableLengthSimd = seqan::Tag<TestAlignSimdVariableLength_>;
-
-struct TestAlignSimdEqualLength_;
-using EqualLengthSimd = seqan::Tag<TestAlignSimdEqualLength_>;
-
-template <typename TAlphabet, typename TSimdLength>
-struct TestSequences_;
-
-template <>
-struct TestSequences_<seqan::Dna, EqualLengthSimd>
-{
-    using TSeq = seqan::String<seqan::Dna>;
-
-    static auto
-    getSequences()
-    {
-        seqan::StringSet<TSeq> set;
-        appendValue(set, "AGCGACTGCAAACATCAGATCAGAG");
-        appendValue(set, "TAATACTAGCATGCGATAAGTCCCT");
-        appendValue(set, "GGCACGTGGATGGTTTAGAGGAATC");
-        appendValue(set, "AGATTCAAGTCTGGTTAACCATCAA");
-        appendValue(set, "ACAGGTCTTGAGTCTAAAATTGTCG");
-        appendValue(set, "TCTCCTGCGTACGAGATGGAAATAC");
-        appendValue(set, "TAGGTAACTACAGGGACTCCGACGT");
-        appendValue(set, "TATGTACGTTGCTCCGTCAGAGGCG");
-
-        appendValue(set, "CCATTCAGGATCACGTTACCGCGAA");
-        appendValue(set, "AAAAAGGGACCAGGAGCTCTTCTCC");
-        appendValue(set, "CCTGCGGTCACGTCTATAGAAATTA");
-        appendValue(set, "CACCATTAACCCTCCTGAGAACCGG");
-        appendValue(set, "GAGGCGGGAATCCGTCACGTATGAG");
-        appendValue(set, "AAGGTATTTGCCCGATAATCAATAC");
-        appendValue(set, "CCCAGGCTTCTAACTTTTTCCACTC");
-        appendValue(set, "GCTTGAGCCGGCTAGGCCTTTCTGC");
-
-        appendValue(set, "ATCTCGGGTCCTGCCCAACCGGTCT");
-        appendValue(set, "AACAAGGGACCAGGAGCTCTTCTCC");
-        appendValue(set, "ACACGCTAATATAGCGAATCACCGA");
-        appendValue(set, "GAACCCGGCGCCACGCAATGGAACG");
-        appendValue(set, "TCCTTAACTCCGGCAGGCAATTAAA");
-        appendValue(set, "ACAGAAAAATAGGCGAATGAATCTT");
-        appendValue(set, "GGGAACGTATGTATAACGCAAAAAA");
-        appendValue(set, "TTCTCTGTGTATCGAAGAATGGCCT");
-
-        appendValue(set, "CCGAAGTTTCGATGGACTGGTGCCA");
-        appendValue(set, "ACGCGCAGGCATAGTTTTAGGAGAA");
-        appendValue(set, "TTATTCGGGGGCAGTGACAACCAAC");
-
-        seqan::StringSet<TSeq>  set2(set);
-        std::sort(seqan::begin(set2, seqan::Standard()), seqan::end(set2, seqan::Standard()),
-                  [](auto& strA, auto& strB){ return seqan::isLess(strA, strB); });
-        return std::make_tuple(set, set2);
-    }
-};
-
-template <>
-struct TestSequences_<seqan::Dna, VariableLengthSimd>
-{
-    using TSeq = seqan::String<seqan::Dna>;
-
-    static auto
-    getSequences()
-    {
-        seqan::StringSet<TSeq> set;
-        appendValue(set, "AGCGACTGCAAACATCAGATCAGAGGTAGAG");
-        appendValue(set, "TAATACTAGCATGCGATAAGTCCCT");
-        appendValue(set, "GGCACGTGTGGTTTAGAGGAATC");
-        appendValue(set, "AGATTCAAGTCTGGTTAACCATCAA");
-        appendValue(set, "ACAGGTCTTGAGTCTAAAATTGTCGAA");
-        appendValue(set, "TCTCCTGCGTACGAGATGGAAATAC");
-        appendValue(set, "TAGGTAACTACAGGGACACGT");
-        appendValue(set, "TATGTACGTCTCCGTCAGAGGCG");
-
-        appendValue(set, "CCATTCAGGATCACGTTACCGCGAAGTACCC");
-        appendValue(set, "AAGGGACCAGGAGCTCTTCTCC");
-        appendValue(set, "CCTGCGGTCACGTCTATAGAAATT");
-        appendValue(set, "CACCATTAACCCTCCTGAGAACCGAGTAGG");
-        appendValue(set, "GAGGCGGGAATCCGTCACGTATGAG");
-        appendValue(set, "AAGGTATTTGCCCGATAATCAATACGATGAGATAGAGAGATAGAATAGAGAAGGGACCGCGCATGACTACGATCGACTGACTACGA");
-        appendValue(set, "CGAGTATATCGAGAGAGGTCACG");
-        appendValue(set, "GCTTGAGCCGGCTAGGCTCTGC");
-
-        appendValue(set, "ATCTCGGGTCCTGCCAACCGGTCT");
-        appendValue(set, "AAAAAGGGACCAGGAGCTCTTCTCC");
-        appendValue(set, "ACACGCTAATATAGCGAATCACCGA");
-        appendValue(set, "AATGGAACG");
-        appendValue(set, "TCCTTAACTCCGGCAGGCAATTATACCGGACTGACACTTAAA");
-        appendValue(set, "ACAGAAAAATAGGCGAATGAAACACTCTT");
-        appendValue(set, "GGGAACGTATGTATAACGCAAAAA");
-        appendValue(set, "TTCTCTGTGTATCGAAGAATGCT");
-
-        appendValue(set, "CCGAAGTTTCGATGGATGGATTCCACACACCTGGTGCCA");
-        appendValue(set, "ACGCGCAGGCATAGTTGGAGAA");
-        appendValue(set, "TTATTCGGGGGCAGTGACAACACTTAGCGACTAC");
-        
-        auto set2(set);
-        std::sort(seqan::begin(set2, seqan::Standard()), seqan::end(set2, seqan::Standard()),
-                  [](auto& strA, auto& strB){ return seqan::isLess(strA, strB); });
-        return std::make_tuple(set, set2);
-    }
-};
-
-template <>
-struct TestSequences_<seqan::AminoAcid, EqualLengthSimd>
-{
-    using TSeq = seqan::String<seqan::AminoAcid>;
-
-    static auto
-    getSequences()
-    {
-        seqan::StringSet<TSeq> set;
-        appendValue(set, "FNQSAEYPDISLHCGVLKWRATLGT");
-        appendValue(set, "EIKSDVLLHRPGNIGMQVAESYFAT");
-        appendValue(set, "PIIMWSMKNRTIERLPTGVLMISHT");
-        appendValue(set, "FMATNEKVHCACGADYQMIIDCNEA");
-        appendValue(set, "MFHQTSNANWMFVSNKFHIKFGTLD");
-        appendValue(set, "SNEMGQCFPHEPACFFDKDFRLFIN");
-        appendValue(set, "FPWAHYVVHTLREHRKDANHRSTSY");
-        appendValue(set, "QYRNTESMGCEMRCFTETIMIAGVA");
-
-        appendValue(set, "VVRMDGKEVLKQHVPTYADKHPTGQ");
-        appendValue(set, "TMLKWCEWCFAEFPPFASEPKFPPN");
-        appendValue(set, "GTWGWVDGVHHTMGEQCGPGRACWG");
-        appendValue(set, "ECDFQTWYFYCVNQEIFELFICCMG");
-        appendValue(set, "KRRELNGQERGGWWTVDGPGVSMGT");
-        appendValue(set, "CWAAHYVCWRTKQKQLVAFQRLNCI");
-        appendValue(set, "NRLVGFQIHCFLIRCVEPGQTHTID");
-        appendValue(set, "AYYVRGFMMGQMYGRPVILMTFTKP");
-
-        appendValue(set, "SFTQPVELHIPHYWWHLAYFMIMFY");
-        appendValue(set, "PMNKMFDFNNHQDLLTFTKRFPTPW");
-        appendValue(set, "VIPMIYHDWSIISALMMQKDIYYIA");
-        appendValue(set, "TPGMWGMATLTGNFNSIFVSKYVKN");
-        appendValue(set, "GKELWGMVIARAGMAVQNMYSRDTF");
-        appendValue(set, "VHASDLYAKCYSNCVYQENIDIAEV");
-        appendValue(set, "KQSGTLSGPQYWENVHRVLEDYPKE");
-        appendValue(set, "DPHGYCFYEGTFAWDVEVHEFNNKD");
-
-        appendValue(set, "NMQDVIGGKSLAQHSSVTYKAQQEH");
-        appendValue(set, "CQTPRWECSLNFDEKEAADLMIDVS");
-        appendValue(set, "PMMDLDHCMLIECLRPHNRDNCARH");
-
-        decltype(set) set2(set);
-        std::sort(seqan::begin(set2, seqan::Standard()), seqan::end(set2, seqan::Standard()),
-                  [](auto& strA, auto& strB){ return seqan::isLess(strA, strB); });
-        return std::make_tuple(set, set2);
-    }
-};
-
-template <>
-struct TestSequences_<seqan::AminoAcid, VariableLengthSimd>
-{
-    using TSeq = seqan::String<seqan::AminoAcid>;
-
-    static auto
-    getSequences()    {
-        seqan::StringSet<TSeq> set;
-        appendValue(set, "FNQSAEYPDISHCGVMQLKWRATLGT");
-        appendValue(set, "EIKSDVLLHRWSMKNPGNILMIDVGMQVAESYFAT");
-        appendValue(set, "PIIMWSMKNRTIEPTGLMISHT");
-        appendValue(set, "FMATNEKVHCACGWSMKNADLMIDVYQMIIDCNEA");
-        appendValue(set, "MWSMKNFHQTSNANWMFVSNMQKFHIKFGTLD");
-        appendValue(set, "SNEGQCFPHEPACFWSMKFDKDFRLFIN");
-        appendValue(set, "FPWAHYVVHTLREHMQRKDANHRSTSY");
-        appendValue(set, "QYRNTWSMKNESMGCEMRFLMIVTETIMIAGVA");
-
-        appendValue(set, "VVRMDGKEVLWSMKNKQHVPTYADKHPTGQ");
-        appendValue(set, "TMLKWCEWCFALMIDVEFPPFASEPKFPPN");
-        appendValue(set, "GTWGVDGVHHWSMWSMKNLMIDVTMGEQCGPGRACWG");
-        appendValue(set, "ECDFQTWYFYCVNQMQEIFELFICCMG");
-        appendValue(set, "KRREWSMKNLNGQERGGWWTVDGPGVSMGT");
-        appendValue(set, "CWAAHYCWRWWSMKNSMKNTKLMIDVQMQKQLVAFQRLNCI");
-        appendValue(set, "NRLVGFQIHCFIRCVEPGQTHTID");
-        appendValue(set, "AYYVRGFMMGQMMQYGRPVILMTFTKP");
-
-        appendValue(set, "SFTQPVELHIPHYWLMIDVWHLAYFMIMFY");
-        appendValue(set, "PMNKMFDFNHQMQDLLTFTKPTPW");
-        appendValue(set, "VIPMIYHDWSIISALMMLMIDVQKDIYYIA");
-        appendValue(set, "TPGMWGMATLTGMQNFNSFVSKYVKN");
-        appendValue(set, "GKELWGMVIARAGMAVQNLMIDVMYSRDTF");
-        appendValue(set, "VHASDLWSNYAKCYSNCVYQEIDIAEV");
-        appendValue(set, "KQSGTLSMQGPYWENVHRVLLMIDVEDYPKE");
-        appendValue(set, "DPHGYCFMQYEGTFAWDVEVHEFNNKD");
-
-        appendValue(set, "NMQDVIGGKSLAQHSSVTYAQQEH");
-        appendValue(set, "CQTPRWECMQSLNFDEKEAADLMIDVS");
-        appendValue(set, "PMMDLDWSMKNMLIECLRPHNRMQDNLMIDVCARH");
-        
-        auto set2(set);
-        std::sort(seqan::begin(set2, seqan::Standard()), seqan::end(set2, seqan::Standard()),
-                  [](auto& strA, auto& strB){ return seqan::isLess(strA, strB); });
-        return std::make_tuple(set, set2);
-    }
-};
-
-struct LocalAlignTester_
-{
-    template <typename TAlign,
-              typename TScoreValue, typename TScoreSpec,
-              typename TConfig>
-    static auto
-    run(TAlign & align,
-        seqan::Score<TScoreValue, TScoreSpec> const & score,
-        TConfig const &,
-        int const lDiag,
-        int const uDiag)
-    {
-        if (lDiag == std::numeric_limits<int>::min() && uDiag == std::numeric_limits<int>::max())
-            return localAlignment(align, score);
-        else
-            return localAlignment(align, score, lDiag, uDiag);
-    }
-};
-
-struct GlobalAlignTester_
-{
-    template <typename TAlign,
-              typename TScoreValue, typename TScoreSpec,
-              typename TConfig>
-    static auto
-    run(TAlign & align,
-        seqan::Score<TScoreValue, TScoreSpec> const & score,
-        TConfig const & config,
-        int const lDiag,
-        int const uDiag)
-    {
-        if (lDiag == std::numeric_limits<int>::min() && uDiag == std::numeric_limits<int>::max())
-            return globalAlignment(align, score, config);
-        else
-            return globalAlignment(align, score, config, lDiag, uDiag);
-    }
-};
-
-struct GlobalAlignScoreTester_
-{
-    template <typename TStringsH,
-              typename TStringsV,
-              typename TScoreValue, typename TScoreSpec,
-              typename TConfig>
-    static auto
-    run(TStringsH const & strH,
-        TStringsV const & strV,
-        seqan::Score<TScoreValue, TScoreSpec> const & score,
-        TConfig const & config,
-        int const lDiag,
-        int const uDiag)
-    {
-        if (lDiag == std::numeric_limits<int>::min() && uDiag == std::numeric_limits<int>::max())
-            return globalAlignmentScore(strH, strV, score, config);
-        else
-            return globalAlignmentScore(strH, strV, score, config, lDiag, uDiag);
-    }
-};
-}  // namespace test_align_simd
-}  // namespace impl
-
-// ----------------------------------------------------------------------------
-// Class SimdAlignTest
-// ----------------------------------------------------------------------------
-
-// Common test class instance, which stores the types to be accessed.
-template <typename TTuple>
-class SimdAlignTest : public seqan::Test
-{
-public:
-    using TAlignConfig = std::tuple_element_t<0, TTuple>;
-    using TLengthParam = std::tuple_element_t<1, TTuple>;
-    using TBandSwitch = std::tuple_element_t<2, TTuple>;
-};
-
-// ----------------------------------------------------------------------------
-// Configuration of typed tests for global alignment.
-// ----------------------------------------------------------------------------
-
-template <typename T>
-class SimdAlignTestCommon : public SimdAlignTest<T>
-{};
-
-typedef
-        seqan::TagList<std::tuple<seqan::AlignConfig<>,                         impl::test_align_simd::EqualLengthSimd,     seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<>,                         impl::test_align_simd::VariableLengthSimd,  seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<true, true, true, true>,   impl::test_align_simd::EqualLengthSimd,     seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<true, true, true, true>,   impl::test_align_simd::VariableLengthSimd,  seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<true, false, false, true>, impl::test_align_simd::EqualLengthSimd,     seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<true, false, false, true>, impl::test_align_simd::VariableLengthSimd,  seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<false, true, true, false>, impl::test_align_simd::EqualLengthSimd,     seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<false, true, true, false>, impl::test_align_simd::VariableLengthSimd,  seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<>,                         impl::test_align_simd::EqualLengthSimd,     seqan::BandOn>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<true, true, true, true>,   impl::test_align_simd::EqualLengthSimd,     seqan::BandOn>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<true, false, false, true>, impl::test_align_simd::EqualLengthSimd,     seqan::BandOn>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<false, true, true, false>, impl::test_align_simd::EqualLengthSimd,     seqan::BandOn>
-        > > > > > > > > > > > > SimdAlignTestCommonCommonTypes;
-
-SEQAN_TYPED_TEST_CASE(SimdAlignTestCommon, SimdAlignTestCommonCommonTypes);
-
-// ----------------------------------------------------------------------------
-// Configuration of typed tests for local alignment.
-// ----------------------------------------------------------------------------
-
-template <typename T>
-class SimdAlignLocalTestCommon : public SimdAlignTest<T>
-{};
-
-typedef
-        seqan::TagList<std::tuple<seqan::AlignConfig<>, impl::test_align_simd::EqualLengthSimd,    seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<>, impl::test_align_simd::VariableLengthSimd, seqan::BandOff>,
-        seqan::TagList<std::tuple<seqan::AlignConfig<>, impl::test_align_simd::EqualLengthSimd,    seqan::BandOn>
-        > > > SimdAlignLocalTestCommonCommonTypes;
-
-SEQAN_TYPED_TEST_CASE(SimdAlignLocalTestCommon, SimdAlignLocalTestCommonCommonTypes);
-
-// ----------------------------------------------------------------------------
-// Function testAlignSimd()
-// ----------------------------------------------------------------------------
-
-template <typename TAlphabet,
-          typename TFunctor,
-          typename TScoreValue, typename TScoreSpec,
-          typename TAlignConfig,
-          typename TSimdLength>
-void testAlignSimd(TFunctor const &,
-                   seqan::Score<TScoreValue, TScoreSpec> const & score,
-                   TAlignConfig const & config,
-                   TSimdLength const & /*tag*/,
-                   int const lDiag = std::numeric_limits<int>::min(),
-                   int const uDiag = std::numeric_limits<int>::max())
-{
-    auto sets = impl::test_align_simd::TestSequences_<TAlphabet, TSimdLength>::getSequences();
-
-    // Prepare an align object with the sequences.
-    seqan::StringSet<seqan::Align<seqan::String<TAlphabet> > > alignments;
-    resize(alignments, length(std::get<0>(sets)));
-    auto zipCont = makeZipView(alignments, std::get<0>(sets), std::get<1>(sets));
-
-    for(auto tuple : zipCont)
-    {
-        resize(rows(std::get<0>(tuple)), 2);
-        assignSource(row(std::get<0>(tuple), 0), std::get<1>(tuple));
-        assignSource(row(std::get<0>(tuple), 1), std::get<2>(tuple));
-    }
-
-    // Run the SIMD accelerated alignment.
-    seqan::String<TScoreValue> scores = TFunctor::run(alignments, score, config, lDiag, uDiag);
-    SEQAN_ASSERT_EQ(length(scores), length(alignments));
-
-    // Check correctness of alignments using sequential alignment.
-    auto zipRes = makeZipView(scores, alignments);
-    for(auto res : zipRes)
-    {
-        typename std::decay<decltype(std::get<1>(res))>::type goldAlign;
-        resize(rows(goldAlign), 2);
-        assignSource(row(goldAlign, 0), source(row(std::get<1>(res), 0)));
-        assignSource(row(goldAlign, 1), source(row(std::get<1>(res), 1)));
-
-        TScoreValue goldScore = TFunctor::run(goldAlign, score, config, lDiag, uDiag);
-
-        SEQAN_ASSERT_EQ(std::get<0>(res), goldScore);
-        SEQAN_ASSERT(row(std::get<1>(res), 0) == row(goldAlign, 0));
-        SEQAN_ASSERT(row(std::get<1>(res), 1) == row(goldAlign, 1));
-    }
-}
-
-// Helper function to set band parameters.
-template <typename TAlphabet,
-          typename TFunctor,
-          typename TScoreValue, typename TScoreSpec,
-          typename TAlignConfig,
-          typename TSimdLength,
-          typename TBandFlag>
-void testAlignSimd(TFunctor const &,
-                   seqan::Score<TScoreValue, TScoreSpec> const & score,
-                   TAlignConfig const & config,
-                   TSimdLength const & /*tag*/,
-                   TBandFlag const &)
-{
-    if (seqan::IsSameType<TBandFlag, seqan::BandOff>::VALUE)
-        testAlignSimd<TAlphabet>(TFunctor(), score, config, TSimdLength());
-    else
-        testAlignSimd<TAlphabet>(TFunctor(), score, config, TSimdLength(), -4, 6);
-}
-
-// ----------------------------------------------------------------------------
-// Function testAlignScoreSimd()
-// ----------------------------------------------------------------------------
-
-template <typename TAlphabet,
-          typename TTester,
-          typename TScoreValue, typename TScoreSpec,
-          typename TAlignConfig,
-          typename TSimdLength>
-void testAlignSimdScore(TTester const &,
-                        seqan::Score<TScoreValue, TScoreSpec> const & score,
-                        TAlignConfig const & config,
-                        TSimdLength const & /*tag*/,
-                        int const lDiag = std::numeric_limits<int>::min(),
-                        int const uDiag = std::numeric_limits<int>::max())
-{
-    auto sets = impl::test_align_simd::TestSequences_<TAlphabet, TSimdLength>::getSequences();
-
-    seqan::String<TScoreValue> scores = TTester::run(std::get<0>(sets), std::get<1>(sets), score, config, lDiag, uDiag);
-
-    SEQAN_ASSERT_EQ(length(scores), length(std::get<0>(sets)));
-
-    auto zipRes = makeZipView(scores, std::get<0>(sets), std::get<1>(sets));
-    for(auto res : zipRes)
-    {
-        TScoreValue goldScore = TTester::run(std::get<1>(res), std::get<2>(res), score, config, lDiag, uDiag);
-        SEQAN_ASSERT_EQ(std::get<0>(res), goldScore);
-    }
-}
-
-// Helper function to set band parameters.
-template <typename TAlphabet,
-          typename TFunctor,
-          typename TScoreValue, typename TScoreSpec,
-          typename TAlignConfig,
-          typename TSimdLength,
-          typename TBandFlag>
-void testAlignSimdScore(TFunctor const &,
-                        seqan::Score<TScoreValue, TScoreSpec> const & score,
-                        TAlignConfig const & config,
-                        TSimdLength const & /*tag*/,
-                        TBandFlag const &)
-{
-    if (seqan::IsSameType<TBandFlag, seqan::BandOff>::VALUE)
-        testAlignSimdScore<TAlphabet>(TFunctor(), score, config, TSimdLength());
-    else
-        testAlignSimdScore<TAlphabet>(TFunctor(), score, config, TSimdLength(), -4, 6);
-}
-
-// ----------------------------------------------------------------------------
-// Global Alignments.
-// ----------------------------------------------------------------------------
-
-SEQAN_TYPED_TEST(SimdAlignTestCommon, Linear_Align)
-{
-    using TAlignConf = typename TestFixture::TAlignConfig;
-    using TLengthParam = typename TestFixture::TLengthParam;
-    using TBandSwitch = typename TestFixture::TBandSwitch;
-
-    testAlignSimd<seqan::Dna>(impl::test_align_simd::GlobalAlignTester_(), seqan::Score<int>(2, -1, -1),
-                              TAlignConf(), TLengthParam(), TBandSwitch());
-    testAlignSimd<seqan::AminoAcid>(impl::test_align_simd::GlobalAlignTester_(), seqan::Blosum62(-2),
-                                    TAlignConf(), TLengthParam(), TBandSwitch());
-}
-
-SEQAN_TYPED_TEST(SimdAlignTestCommon, Linear_Score)
-{
-    using TAlignConf = typename TestFixture::TAlignConfig;
-    using TLengthParam = typename TestFixture::TLengthParam;
-    using TBandSwitch = typename TestFixture::TBandSwitch;
-
-    testAlignSimdScore<seqan::Dna>(impl::test_align_simd::GlobalAlignScoreTester_(), seqan::Score<int>(2, -1, -1),
-                                   TAlignConf(), TLengthParam(), TBandSwitch());
-    testAlignSimdScore<seqan::AminoAcid>(impl::test_align_simd::GlobalAlignScoreTester_(), seqan::Blosum62(-2),
-                                         TAlignConf(), TLengthParam(), TBandSwitch());
-}
-
-SEQAN_TYPED_TEST(SimdAlignTestCommon, Affine_Align)
-{
-    using TAlignConf = typename TestFixture::TAlignConfig;
-    using TLengthParam = typename TestFixture::TLengthParam;
-    using TBandSwitch = typename TestFixture::TBandSwitch;
-
-    testAlignSimd<seqan::Dna>(impl::test_align_simd::GlobalAlignTester_(), seqan::Score<int>(2, -1, -1, -3),
-                              TAlignConf(), TLengthParam(), TBandSwitch());
-    testAlignSimd<seqan::AminoAcid>(impl::test_align_simd::GlobalAlignTester_(), seqan::Blosum62(-2, -4),
-                                    TAlignConf(), TLengthParam(), TBandSwitch());
-}
-
-SEQAN_TYPED_TEST(SimdAlignTestCommon, Affine_Score)
-{
-    using TAlignConf = typename TestFixture::TAlignConfig;
-    using TLengthParam = typename TestFixture::TLengthParam;
-    using TBandSwitch = typename TestFixture::TBandSwitch;
-
-    testAlignSimdScore<seqan::Dna>(impl::test_align_simd::GlobalAlignScoreTester_(), seqan::Score<int>(2, -1, -1, -3),
-                                   TAlignConf(), TLengthParam(), TBandSwitch());
-    testAlignSimdScore<seqan::AminoAcid>(impl::test_align_simd::GlobalAlignScoreTester_(), seqan::Blosum62(-2, -4),
-                                         TAlignConf(), TLengthParam(), TBandSwitch());
-}
-
-// ----------------------------------------------------------------------------
-// Local Alignments.
-// ----------------------------------------------------------------------------
-
-SEQAN_TYPED_TEST(SimdAlignLocalTestCommon, Linear_Align)
-{
-    using TAlignConf = typename TestFixture::TAlignConfig;
-    using TLengthParam = typename TestFixture::TLengthParam;
-    using TBandSwitch = typename TestFixture::TBandSwitch;
-
-    testAlignSimd<seqan::Dna>(impl::test_align_simd::LocalAlignTester_(), seqan::Score<int>(2, -1, -1),
-                              TAlignConf(), TLengthParam(), TBandSwitch());
-    testAlignSimd<seqan::AminoAcid>(impl::test_align_simd::LocalAlignTester_(), seqan::Blosum62(-2),
-                                    TAlignConf(), TLengthParam(), TBandSwitch());
-}
-
-SEQAN_TYPED_TEST(SimdAlignLocalTestCommon, Affine_Align)
-{
-    using TAlignConf = typename TestFixture::TAlignConfig;
-    using TLengthParam = typename TestFixture::TLengthParam;
-    using TBandSwitch = typename TestFixture::TBandSwitch;
-
-    testAlignSimd<seqan::Dna>(impl::test_align_simd::LocalAlignTester_(), seqan::Score<int>(2, -1, -1, -3),
-                              TAlignConf(), TLengthParam(), TBandSwitch());
-    testAlignSimd<seqan::AminoAcid>(impl::test_align_simd::LocalAlignTester_(), seqan::Blosum62(-2, -4),
-                                    TAlignConf(), TLengthParam(), TBandSwitch());
-}
-
-#endif  // #ifndef TESTS_ALIGN_TEST_ALIGN_SIMD_H_
diff --git a/tests/align/test_align_simd_base.h b/tests/align/test_align_simd_base.h
new file mode 100644
index 0000000..149da57
--- /dev/null
+++ b/tests/align/test_align_simd_base.h
@@ -0,0 +1,265 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef TESTS_ALIGN_TEST_ALIGN_SIMD_BASE_H_
+#define TESTS_ALIGN_TEST_ALIGN_SIMD_BASE_H_
+
+#include <tuple>
+
+#include <seqan/basic.h>
+#include <seqan/align.h>
+
+#include "test_mock.h"
+
+// ----------------------------------------------------------------------------
+// Class SimdAlignTest
+// ----------------------------------------------------------------------------
+
+// Common test class instance, which stores the types to be accessed.
+template <typename TTuple>
+class SimdAlignTest : public seqan::Test
+{
+public:
+    using TAlignConfig = std::tuple_element_t<0, TTuple>;
+    using TLengthParam = std::tuple_element_t<1, TTuple>;
+    using TBandSwitch = std::tuple_element_t<2, TTuple>;
+};
+
+namespace impl
+{
+namespace test_align_simd
+{
+
+struct LocalAlignTester_
+{
+    template <typename TAlign,
+              typename TScoreValue, typename TScoreSpec,
+              typename TConfig>
+    static auto
+    run(TAlign & align,
+        seqan::Score<TScoreValue, TScoreSpec> const & score,
+        TConfig const &,
+        int const lDiag,
+        int const uDiag)
+    {
+        if (lDiag == std::numeric_limits<int>::min() && uDiag == std::numeric_limits<int>::max())
+            return localAlignment(align, score);
+        else
+            return localAlignment(align, score, lDiag, uDiag);
+    }
+};
+
+struct GlobalAlignTester_
+{
+    template <typename TAlign,
+              typename TScoreValue, typename TScoreSpec,
+              typename TConfig>
+    static auto
+    run(TAlign & align,
+        seqan::Score<TScoreValue, TScoreSpec> const & score,
+        TConfig const & config,
+        int const lDiag,
+        int const uDiag)
+    {
+        if (lDiag == std::numeric_limits<int>::min() && uDiag == std::numeric_limits<int>::max())
+            return globalAlignment(align, score, config);
+        else
+            return globalAlignment(align, score, config, lDiag, uDiag);
+    }
+};
+
+struct GlobalAlignScoreTester_
+{
+    template <typename TStringsH,
+              typename TStringsV,
+              typename TScoreValue, typename TScoreSpec,
+              typename TConfig>
+    static auto
+    run(TStringsH const & strH,
+        TStringsV const & strV,
+        seqan::Score<TScoreValue, TScoreSpec> const & score,
+        TConfig const & config,
+        int const lDiag,
+        int const uDiag)
+    {
+        if (lDiag == std::numeric_limits<int>::min() && uDiag == std::numeric_limits<int>::max())
+            return globalAlignmentScore(strH, strV, score, config);
+        else
+            return globalAlignmentScore(strH, strV, score, config, lDiag, uDiag);
+    }
+};
+
+struct LocalScoreTester_
+{
+    template <typename TStringsH,
+              typename TStringsV,
+              typename TScoreValue, typename TScoreSpec,
+              typename TConfig>
+    static auto
+    run(TStringsH const & strH,
+        TStringsV const & strV,
+        seqan::Score<TScoreValue, TScoreSpec> const & score,
+        TConfig const & /*config*/,
+        int const lDiag,
+        int const uDiag)
+    {
+        if (lDiag == seqan::MinValue<int>::VALUE && uDiag == seqan::MaxValue<int>::VALUE)
+            return localAlignmentScore(strH, strV, score);
+        else
+            return localAlignmentScore(strH, strV, score, lDiag, uDiag);
+    }
+};
+}  // namespace test_align_simd
+}  // namespace impl
+
+// ----------------------------------------------------------------------------
+// Function testAlignSimd()
+// ----------------------------------------------------------------------------
+
+template <typename TAlphabet,
+          typename TFunctor,
+          typename TScoreValue, typename TScoreSpec,
+          typename TAlignConfig,
+          typename TSimdLength>
+void testAlignSimd(TFunctor const &,
+                   seqan::Score<TScoreValue, TScoreSpec> const & score,
+                   TAlignConfig const & config,
+                   TSimdLength const & /*tag*/,
+                   int const lDiag = std::numeric_limits<int>::min(),
+                   int const uDiag = std::numeric_limits<int>::max())
+{
+    auto sets = impl::test_align_mock::TestSequences_<TAlphabet, TSimdLength>::getSequences();
+
+    // Prepare an align object with the sequences.
+    seqan::StringSet<seqan::Align<seqan::String<TAlphabet> > > alignments;
+    resize(alignments, length(std::get<0>(sets)));
+    auto zipCont = makeZipView(alignments, std::get<0>(sets), std::get<1>(sets));
+
+    for (auto tuple : zipCont)
+    {
+        resize(rows(std::get<0>(tuple)), 2);
+        assignSource(row(std::get<0>(tuple), 0), std::get<1>(tuple));
+        assignSource(row(std::get<0>(tuple), 1), std::get<2>(tuple));
+    }
+
+    // Run the SIMD accelerated alignment.
+    seqan::String<TScoreValue> scores = TFunctor::run(alignments, score, config, lDiag, uDiag);
+    SEQAN_ASSERT_EQ(length(scores), length(alignments));
+
+    // Check correctness of alignments using sequential alignment.
+    auto zipRes = makeZipView(scores, alignments);
+    for (auto res : zipRes)
+    {
+        typename std::decay<decltype(std::get<1>(res))>::type goldAlign;
+        resize(rows(goldAlign), 2);
+        assignSource(row(goldAlign, 0), source(row(std::get<1>(res), 0)));
+        assignSource(row(goldAlign, 1), source(row(std::get<1>(res), 1)));
+
+        TScoreValue goldScore = TFunctor::run(goldAlign, score, config, lDiag, uDiag);
+
+        SEQAN_ASSERT_EQ(std::get<0>(res), goldScore);
+        SEQAN_ASSERT(row(std::get<1>(res), 0) == row(goldAlign, 0));
+        SEQAN_ASSERT(row(std::get<1>(res), 1) == row(goldAlign, 1));
+    }
+}
+
+// Helper function to set band parameters.
+template <typename TAlphabet,
+          typename TFunctor,
+          typename TScoreValue, typename TScoreSpec,
+          typename TAlignConfig,
+          typename TSimdLength,
+          typename TBandFlag>
+void testAlignSimd(TFunctor const &,
+                   seqan::Score<TScoreValue, TScoreSpec> const & score,
+                   TAlignConfig const & config,
+                   TSimdLength const & /*tag*/,
+                   TBandFlag const &)
+{
+    if (seqan::IsSameType<TBandFlag, seqan::BandOff>::VALUE)
+        testAlignSimd<TAlphabet>(TFunctor(), score, config, TSimdLength());
+    else
+        testAlignSimd<TAlphabet>(TFunctor(), score, config, TSimdLength(), -4, 6);
+}
+
+// ----------------------------------------------------------------------------
+// Function testAlignScoreSimd()
+// ----------------------------------------------------------------------------
+
+template <typename TAlphabet,
+          typename TTester,
+          typename TScoreValue, typename TScoreSpec,
+          typename TAlignConfig,
+          typename TSimdLength>
+void testAlignSimdScore(TTester const &,
+                        seqan::Score<TScoreValue, TScoreSpec> const & score,
+                        TAlignConfig const & config,
+                        TSimdLength const & /*tag*/,
+                        int const lDiag = std::numeric_limits<int>::min(),
+                        int const uDiag = std::numeric_limits<int>::max())
+{
+    auto sets = impl::test_align_mock::TestSequences_<TAlphabet, TSimdLength>::getSequences();
+
+    seqan::String<TScoreValue> scores = TTester::run(std::get<0>(sets), std::get<1>(sets), score, config, lDiag, uDiag);
+
+    SEQAN_ASSERT_EQ(length(scores), length(std::get<0>(sets)));
+
+    auto zipRes = makeZipView(scores, std::get<0>(sets), std::get<1>(sets));
+    for (auto res : zipRes)
+    {
+        TScoreValue goldScore = TTester::run(std::get<1>(res), std::get<2>(res), score, config, lDiag, uDiag);
+        SEQAN_ASSERT_EQ(std::get<0>(res), goldScore);
+    }
+}
+
+// Helper function to set band parameters.
+template <typename TAlphabet,
+          typename TFunctor,
+          typename TScoreValue, typename TScoreSpec,
+          typename TAlignConfig,
+          typename TSimdLength,
+          typename TBandFlag>
+void testAlignSimdScore(TFunctor const &,
+                        seqan::Score<TScoreValue, TScoreSpec> const & score,
+                        TAlignConfig const & config,
+                        TSimdLength const & /*tag*/,
+                        TBandFlag const &)
+{
+    if (seqan::IsSameType<TBandFlag, seqan::BandOff>::VALUE)
+        testAlignSimdScore<TAlphabet>(TFunctor(), score, config, TSimdLength());
+    else
+        testAlignSimdScore<TAlphabet>(TFunctor(), score, config, TSimdLength(), -4, 6);
+}
+
+#endif  // #ifndef TESTS_ALIGN_TEST_ALIGN_SIMD_BASE_H_
diff --git a/tests/align/test_align_simd_global.h b/tests/align/test_align_simd_global.h
new file mode 100644
index 0000000..e14dea6
--- /dev/null
+++ b/tests/align/test_align_simd_global.h
@@ -0,0 +1,122 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef TESTS_ALIGN_TEST_ALIGN_SIMD_GLOBAL_H_
+#define TESTS_ALIGN_TEST_ALIGN_SIMD_GLOBAL_H_
+
+#include "test_align_simd_base.h"
+
+// ----------------------------------------------------------------------------
+// Global Alignments.
+// ----------------------------------------------------------------------------
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Linear_Align)
+{
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    testAlignSimd<seqan::Dna>(impl::test_align_simd::GlobalAlignTester_(), seqan::Score<int>(2, -1, -1),
+                              TAlignConf(), TLengthParam(), TBandSwitch());
+    testAlignSimd<seqan::AminoAcid>(impl::test_align_simd::GlobalAlignTester_(), seqan::Blosum62(-2),
+                                    TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Linear_Score)
+{
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    testAlignSimdScore<seqan::Dna>(impl::test_align_simd::GlobalAlignScoreTester_(), seqan::Score<int>(2, -1, -1),
+                                   TAlignConf(), TLengthParam(), TBandSwitch());
+    testAlignSimdScore<seqan::AminoAcid>(impl::test_align_simd::GlobalAlignScoreTester_(), seqan::Blosum62(-2),
+                                         TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Affine_Align)
+{
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    testAlignSimd<seqan::Dna>(impl::test_align_simd::GlobalAlignTester_(), seqan::Score<int>(2, -1, -1, -3),
+                              TAlignConf(), TLengthParam(), TBandSwitch());
+    testAlignSimd<seqan::AminoAcid>(impl::test_align_simd::GlobalAlignTester_(), seqan::Blosum62(-2, -4),
+                                    TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Dynamic_Score_Matrix_Align)
+{
+    using namespace seqan;
+
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    Score<int, ScoreMatrix<AminoAcid, ScoreSpecSelectable> > dynScore{-2, -4};
+    setScoreMatrixById(dynScore, AminoAcidScoreMatrixID::PAM120);
+
+    testAlignSimd<seqan::AminoAcid>(::impl::test_align_simd::GlobalAlignTester_(), dynScore,
+                                    TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Affine_Score)
+{
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    testAlignSimdScore<seqan::Dna>(impl::test_align_simd::GlobalAlignScoreTester_(), seqan::Score<int>(2, -1, -1, -3),
+                                   TAlignConf(), TLengthParam(), TBandSwitch());
+    testAlignSimdScore<seqan::AminoAcid>(impl::test_align_simd::GlobalAlignScoreTester_(), seqan::Blosum62(-2, -4),
+                                         TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Dynamic_Score_Matrix)
+{
+    using namespace seqan;
+
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    Score<int, ScoreMatrix<AminoAcid, ScoreSpecSelectable> > dynScore{-2, -4};
+    setScoreMatrixById(dynScore, AminoAcidScoreMatrixID::PAM120);
+
+    testAlignSimdScore<seqan::AminoAcid>(::impl::test_align_simd::GlobalAlignScoreTester_(), dynScore,
+                                         TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+#endif  // #ifndef TESTS_ALIGN_TEST_ALIGN_SIMD_GLOBAL_H_
diff --git a/tests/align/test_align_simd.cpp b/tests/align/test_align_simd_global_equal_length.cpp
similarity index 57%
copy from tests/align/test_align_simd.cpp
copy to tests/align/test_align_simd_global_equal_length.cpp
index 405b6b6..1a4ee36 100644
--- a/tests/align/test_align_simd.cpp
+++ b/tests/align/test_align_simd_global_equal_length.cpp
@@ -32,10 +32,34 @@
 // Author: René Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
+
 #include <seqan/basic.h>
 #include <seqan/stream.h>
 
-#include "test_align_simd.h"
+#include "test_align_simd_base.h"
+
+// ----------------------------------------------------------------------------
+// Configuration of typed tests for global alignment.
+// ----------------------------------------------------------------------------
+
+template <typename T>
+class SimdAlignTestCommon : public SimdAlignTest<T>
+{};
+
+typedef
+        seqan::TagList<std::tuple<seqan::AlignConfig<>,                         impl::test_align_mock::EqualLengthSimd,     seqan::BandOff>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<true, true, true, true>,   impl::test_align_mock::EqualLengthSimd,     seqan::BandOff>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<true, false, false, true>, impl::test_align_mock::EqualLengthSimd,     seqan::BandOff>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<false, true, true, false>, impl::test_align_mock::EqualLengthSimd,     seqan::BandOff>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<>,                         impl::test_align_mock::EqualLengthSimd,     seqan::BandOn>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<true, true, true, true>,   impl::test_align_mock::EqualLengthSimd,     seqan::BandOn>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<true, false, false, true>, impl::test_align_mock::EqualLengthSimd,     seqan::BandOn>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<false, true, true, false>, impl::test_align_mock::EqualLengthSimd,     seqan::BandOn>
+        > > > > > > > > SimdAlignGlobalEqualLengthTestTypes;
+
+SEQAN_TYPED_TEST_CASE(SimdAlignTestCommon, SimdAlignGlobalEqualLengthTestTypes);
+
+#include "test_align_simd_global.h"
 
 int main(int argc, char const ** argv) {
     seqan::TestSystem::init(argc, argv);
diff --git a/tests/align/test_align_simd.cpp b/tests/align/test_align_simd_global_variable_length.cpp
similarity index 67%
copy from tests/align/test_align_simd.cpp
copy to tests/align/test_align_simd_global_variable_length.cpp
index 405b6b6..47f107c 100644
--- a/tests/align/test_align_simd.cpp
+++ b/tests/align/test_align_simd_global_variable_length.cpp
@@ -35,7 +35,26 @@
 #include <seqan/basic.h>
 #include <seqan/stream.h>
 
-#include "test_align_simd.h"
+#include "test_align_simd_base.h"
+
+// ----------------------------------------------------------------------------
+// Configuration of typed tests for global alignment.
+// ----------------------------------------------------------------------------
+
+template <typename T>
+class SimdAlignTestCommon : public SimdAlignTest<T>
+{};
+
+typedef
+        seqan::TagList<std::tuple<seqan::AlignConfig<>,                         impl::test_align_mock::VariableLengthSimd,  seqan::BandOff>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<true, true, true, true>,   impl::test_align_mock::VariableLengthSimd,  seqan::BandOff>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<true, false, false, true>, impl::test_align_mock::VariableLengthSimd,  seqan::BandOff>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<false, true, true, false>, impl::test_align_mock::VariableLengthSimd,  seqan::BandOff>
+        > > > > SimdAlignGlobalVariableLengthTestTypes;
+
+SEQAN_TYPED_TEST_CASE(SimdAlignTestCommon, SimdAlignGlobalVariableLengthTestTypes);
+
+#include "test_align_simd_global.h"
 
 int main(int argc, char const ** argv) {
     seqan::TestSystem::init(argc, argv);
diff --git a/tests/align/test_align_simd_local.h b/tests/align/test_align_simd_local.h
new file mode 100644
index 0000000..6faa7fb
--- /dev/null
+++ b/tests/align/test_align_simd_local.h
@@ -0,0 +1,122 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef TESTS_ALIGN_TEST_ALIGN_SIMD_LOCAL_H_
+#define TESTS_ALIGN_TEST_ALIGN_SIMD_LOCAL_H_
+
+#include "test_align_simd_base.h"
+
+// ----------------------------------------------------------------------------
+// Local Alignments.
+// ----------------------------------------------------------------------------
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Linear_Align)
+{
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    testAlignSimd<seqan::Dna>(impl::test_align_simd::LocalAlignTester_(), seqan::Score<int>(2, -1, -1),
+                              TAlignConf(), TLengthParam(), TBandSwitch());
+    testAlignSimd<seqan::AminoAcid>(impl::test_align_simd::LocalAlignTester_(), seqan::Blosum62(-2),
+                                    TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Linear_Score)
+{
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    testAlignSimdScore<seqan::Dna>(impl::test_align_simd::LocalScoreTester_(), seqan::Score<int>(2, -1, -1),
+                                   TAlignConf(), TLengthParam(), TBandSwitch());
+    testAlignSimdScore<seqan::AminoAcid>(impl::test_align_simd::LocalScoreTester_(), seqan::Blosum62(-2),
+                                         TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Affine_Align)
+{
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    testAlignSimd<seqan::Dna>(impl::test_align_simd::LocalAlignTester_(), seqan::Score<int>(2, -1, -1, -3),
+                              TAlignConf(), TLengthParam(), TBandSwitch());
+    testAlignSimd<seqan::AminoAcid>(impl::test_align_simd::LocalAlignTester_(), seqan::Blosum62(-2, -4),
+                                    TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Dynamic_Score_Matrix_Align)
+{
+    using namespace seqan;
+
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    Score<int, ScoreMatrix<AminoAcid, ScoreSpecSelectable> > dynScore{-2, -4};
+    setScoreMatrixById(dynScore, AminoAcidScoreMatrixID::PAM120);
+
+    testAlignSimd<seqan::AminoAcid>(::impl::test_align_simd::LocalAlignTester_(), dynScore,
+                                    TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Affine_Score)
+{
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    testAlignSimdScore<seqan::Dna>(impl::test_align_simd::LocalScoreTester_(), seqan::Score<int>(2, -1, -1, -3),
+                                   TAlignConf(), TLengthParam(), TBandSwitch());
+    testAlignSimdScore<seqan::AminoAcid>(impl::test_align_simd::LocalScoreTester_(), seqan::Blosum62(-2, -4),
+                                         TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+SEQAN_TYPED_TEST(SimdAlignTestCommon, Dynamic_Score_Matrix)
+{
+    using namespace seqan;
+
+    using TAlignConf = typename TestFixture::TAlignConfig;
+    using TLengthParam = typename TestFixture::TLengthParam;
+    using TBandSwitch = typename TestFixture::TBandSwitch;
+
+    Score<int, ScoreMatrix<AminoAcid, ScoreSpecSelectable> > dynScore{-2, -4};
+    setScoreMatrixById(dynScore, AminoAcidScoreMatrixID::PAM120);
+
+    testAlignSimdScore<seqan::AminoAcid>(::impl::test_align_simd::LocalScoreTester_(), dynScore,
+                                         TAlignConf(), TLengthParam(), TBandSwitch());
+}
+
+#endif  // #ifndef TESTS_ALIGN_TEST_ALIGN_SIMD_LOCAL_H_
diff --git a/tests/align/test_align_simd.cpp b/tests/align/test_align_simd_local_equal_length.cpp
similarity index 75%
copy from tests/align/test_align_simd.cpp
copy to tests/align/test_align_simd_local_equal_length.cpp
index 405b6b6..7913980 100644
--- a/tests/align/test_align_simd.cpp
+++ b/tests/align/test_align_simd_local_equal_length.cpp
@@ -35,7 +35,24 @@
 #include <seqan/basic.h>
 #include <seqan/stream.h>
 
-#include "test_align_simd.h"
+#include "test_align_simd_base.h"
+
+// ----------------------------------------------------------------------------
+// Configuration of typed tests for local alignment.
+// ----------------------------------------------------------------------------
+
+template <typename T>
+class SimdAlignTestCommon : public SimdAlignTest<T>
+{};
+
+typedef
+        seqan::TagList<std::tuple<seqan::AlignConfig<>, impl::test_align_mock::EqualLengthSimd,    seqan::BandOff>,
+        seqan::TagList<std::tuple<seqan::AlignConfig<>, impl::test_align_mock::EqualLengthSimd,    seqan::BandOn>
+        > > SimdAlignLocalEqualLengthTestTypes;
+
+SEQAN_TYPED_TEST_CASE(SimdAlignTestCommon, SimdAlignLocalEqualLengthTestTypes);
+
+#include "test_align_simd_local.h"
 
 int main(int argc, char const ** argv) {
     seqan::TestSystem::init(argc, argv);
diff --git a/tests/align/test_align_simd.cpp b/tests/align/test_align_simd_local_variable_length.cpp
similarity index 78%
copy from tests/align/test_align_simd.cpp
copy to tests/align/test_align_simd_local_variable_length.cpp
index 405b6b6..2d70640 100644
--- a/tests/align/test_align_simd.cpp
+++ b/tests/align/test_align_simd_local_variable_length.cpp
@@ -35,7 +35,23 @@
 #include <seqan/basic.h>
 #include <seqan/stream.h>
 
-#include "test_align_simd.h"
+#include "test_align_simd_base.h"
+
+// ----------------------------------------------------------------------------
+// Configuration of typed tests for local alignment.
+// ----------------------------------------------------------------------------
+
+template <typename T>
+class SimdAlignTestCommon : public SimdAlignTest<T>
+{};
+
+typedef
+        seqan::TagList<std::tuple<seqan::AlignConfig<>, impl::test_align_mock::VariableLengthSimd, seqan::BandOff>
+        > SimdAlignLocalVariableLengthTestTypes;
+
+SEQAN_TYPED_TEST_CASE(SimdAlignTestCommon, SimdAlignLocalVariableLengthTestTypes);
+
+#include "test_align_simd_local.h"
 
 int main(int argc, char const ** argv) {
     seqan::TestSystem::init(argc, argv);
diff --git a/tests/align/test_alignment_algorithms_band_position.h b/tests/align/test_alignment_algorithms_band_position.h
index 13b2faf..b7e5d7b 100644
--- a/tests/align/test_alignment_algorithms_band_position.h
+++ b/tests/align/test_alignment_algorithms_band_position.h
@@ -44,7 +44,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case1)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -109,7 +109,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case2)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -172,7 +172,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case3)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -234,7 +234,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case4)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -295,7 +295,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case5)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -359,7 +359,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case6)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -422,7 +422,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case7)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -485,7 +485,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case8)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -547,7 +547,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case9)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -609,7 +609,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case10)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
     //012345678901
@@ -670,7 +670,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case11)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -733,7 +733,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case12)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -795,7 +795,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case13)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
     //012345678901
@@ -857,7 +857,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case14)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -920,7 +920,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case15)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -982,7 +982,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case16)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1043,7 +1043,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case17)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1104,7 +1104,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case18)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1165,7 +1165,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case19)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1226,7 +1226,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case20)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1287,7 +1287,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case21)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1348,7 +1348,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case22)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1409,7 +1409,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case23)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1470,7 +1470,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case24)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1533,7 +1533,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case25)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1595,7 +1595,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case26)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1658,7 +1658,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case27)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1719,7 +1719,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case28)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1781,7 +1781,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case29)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1842,7 +1842,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case30)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
@@ -1903,7 +1903,7 @@ SEQAN_DEFINE_TEST(test_alignment_algorithms_band_position_case31)
 
     typedef DPProfile_<GlobalAlignment_<>, LinearGaps, TracebackOn<> > TDPProfile;
     typedef DPProfile_<GlobalAlignment_<FreeEndGaps_<True, True, True, True> >, LinearGaps, TracebackOn<> > TDPProfileOverlap;
-    typedef DPContext<int, LinearGaps> TDPContext;
+    typedef DPContext<DPCell_<int, LinearGaps>, typename TraceBitMap_<>::Type> TDPContext;
     TDPContext dpContext;
     DPScoutState_<Default> scoutState;
 
diff --git a/tests/align/test_alignment_algorithms_local.h b/tests/align/test_alignment_algorithms_local.h
index f6c1d73..99ce1c7 100644
--- a/tests/align/test_alignment_algorithms_local.h
+++ b/tests/align/test_alignment_algorithms_local.h
@@ -607,6 +607,53 @@ SEQAN_DEFINE_TEST(test_align_local_alignment_enumeration_gaps)
 
         SEQAN_ASSERT_NOT(nextLocalAlignment(gapsH, gapsV, enumerator));
     }
+
+    // Test scoring matrix
+    {
+
+        std::stringstream ssH, ssV;
+
+        String<AminoAcid> strH("IGYELAPIPHTRTMDDFGNWWWKKWIHDDELNYFGTQLLIWHLQEKEGEQ");
+        String<AminoAcid> strV("KHSDQGQIALLIHNTLQDWRPKVECDSPRTMIRRDFDDPQLAPPPHTNHRGNM");
+
+        Gaps<String<AminoAcid>, ArrayGaps> gapsH(strH);
+        Gaps<String<AminoAcid>, ArrayGaps> gapsV(strV);
+
+        Blosum62 scoringScheme;
+        int cutoff =  40;
+
+        LocalAlignmentEnumerator<Blosum62, Unbanded> enumerator(scoringScheme, cutoff);
+
+        SEQAN_ASSERT(nextLocalAlignment(gapsH, gapsV, enumerator));
+        SEQAN_ASSERT_EQ(getScore(enumerator), 69);
+        ssH.clear(); ssH.str(""); ssH << gapsH;
+        SEQAN_ASSERT_EQ(ssH.str(), "GYELAP--IPHTRTMDDFGNWWWK-KWIH-DD-E-L---NYFGT-QLLIW---HLQEKEG");
+        ssV.clear(); ssV.str(""); ssV << gapsV;
+        SEQAN_ASSERT_EQ(ssV.str(), "G-QIA-LLI-HN-TLQD---W--RPK-VECDSPRTMIRRD-FDDPQLA--PPPHTNHR-G");
+
+        SEQAN_ASSERT(nextLocalAlignment(gapsH, gapsV, enumerator));
+        SEQAN_ASSERT_EQ(getScore(enumerator), 57);
+        ssH.clear(); ssH.str(""); ssH << gapsH;
+        SEQAN_ASSERT_EQ(ssH.str(), "KWIHDDELNYFGTQ--LLIWH--LQE---K-E");
+        ssV.clear(); ssV.str(""); ssV << gapsV;
+        SEQAN_ASSERT(ssV.str() == "K--HSDQ----G-QIALLI-HNTLQDWRPKVE");
+
+        SEQAN_ASSERT(nextLocalAlignment(gapsH, gapsV, enumerator));
+        SEQAN_ASSERT_EQ(getScore(enumerator), 51);
+        ssH.clear(); ssH.str(""); ssH << gapsH;
+        SEQAN_ASSERT_EQ(ssH.str(), "IGYE-LA---P-I----PHTRTMD---DFGNWWWKKWIHDD-EL------NYF-GTQL");
+        ssV.clear(); ssV.str(""); ssV << gapsV;
+        SEQAN_ASSERT_EQ(ssV.str(), "I-HNTLQDWRPKVECDSP--RTM-IRRDF----------DDPQLAPPPHTNH-RGN-M");
+
+        SEQAN_ASSERT(nextLocalAlignment(gapsH, gapsV, enumerator));
+        SEQAN_ASSERT_EQ(getScore(enumerator), 46);
+        ssH.clear(); ssH.str(""); ssH << gapsH;
+        SEQAN_ASSERT_EQ(ssH.str(), "I--GYE---LAPIP-HT--RTMDDFGN");
+        ssV.clear(); ssV.str(""); ssV << gapsV;
+        SEQAN_ASSERT_EQ(ssV.str(), "IRRDFDDPQLAP-PPHTNHR-----GN");
+
+        SEQAN_ASSERT_NOT(nextLocalAlignment(gapsH, gapsV, enumerator));
+    }
 }
 
 SEQAN_DEFINE_TEST(test_align_local_alignment_enumeration_fragment)
diff --git a/tests/align/test_alignment_algorithms_local_banded.h b/tests/align/test_alignment_algorithms_local_banded.h
index 846cf94..afe4148 100644
--- a/tests/align/test_alignment_algorithms_local_banded.h
+++ b/tests/align/test_alignment_algorithms_local_banded.h
@@ -502,6 +502,38 @@ SEQAN_DEFINE_TEST(test_align_local_alignment_enumeration_banded_gaps)
 
         SEQAN_ASSERT_NOT(nextLocalAlignment(gapsH, gapsV, enumerator));
     }
+
+    // Test scoring matrix
+    {
+        std::stringstream ssH, ssV;
+
+        String<AminoAcid> strH("IGYELAPIPHTRTMDDFGNWWWKKWIHDDELNYFGTQLLIWHLQEKEGEQ");
+        String<AminoAcid> strV("KHSDQGQIALLIHNTLQDWRPKVECDSPRTMIRRDFDDPQLAPPPHTNHRGNM");
+
+        Gaps<String<AminoAcid>, ArrayGaps> gapsH(strH);
+        Gaps<String<AminoAcid>, ArrayGaps> gapsV(strV);
+
+        Blosum62 scoringScheme;
+        int cutoff =  40;
+
+        LocalAlignmentEnumerator<Blosum62, Banded> enumerator(scoringScheme, -20, 20, cutoff);
+
+        SEQAN_ASSERT(nextLocalAlignment(gapsH, gapsV, enumerator));
+        SEQAN_ASSERT_EQ(getScore(enumerator), 69);
+        ssH.clear(); ssH.str(""); ssH << gapsH;
+        SEQAN_ASSERT_EQ(ssH.str(), "GYELAP--IPHTRTMDDFGNWWWK-KWIH-DD-E--L--NYF-GTQLLIW---HLQEKEG");
+        ssV.clear(); ssV.str(""); ssV << gapsV;
+        SEQAN_ASSERT_EQ(ssV.str(), "G-QIA-LLI-H-NTLQD-----WRPK-VECDSPRTMIRRD-FDDPQ-LA-PPPHTNHR-G");
+
+        SEQAN_ASSERT(nextLocalAlignment(gapsH, gapsV, enumerator));
+        SEQAN_ASSERT_EQ(getScore(enumerator), 51);
+        ssH.clear(); ssH.str(""); ssH << gapsH;
+        SEQAN_ASSERT_EQ(ssH.str(), "IGYE-L---AP-I----PHTRTM--DDFGNWWWKKWIHDD-EL------NYF-GTQL");
+        ssV.clear(); ssV.str(""); ssV << gapsV;
+        SEQAN_ASSERT(ssV.str() == "I-HNTLQDWRPKVECDSP--RTMIRRDF----------DDPQLAPPPHTNH-RG-NM");
+
+        SEQAN_ASSERT_NOT(nextLocalAlignment(gapsH, gapsV, enumerator));
+    }
 }
 
 SEQAN_DEFINE_TEST(test_align_local_alignment_enumeration_banded_fragment)
diff --git a/tests/align/test_alignment_dp_adapt_tracesegments.h b/tests/align/test_alignment_dp_adapt_tracesegments.h
index b883c85..69b9d50 100644
--- a/tests/align/test_alignment_dp_adapt_tracesegments.h
+++ b/tests/align/test_alignment_dp_adapt_tracesegments.h
@@ -50,7 +50,7 @@ testAlign2TracebackTraceSegmentsConstructor()
         SEQAN_ASSERT_EQ(traceSegment._horizontalBeginPos, (TPosition) 0);
         SEQAN_ASSERT_EQ(traceSegment._verticalBeginPos, (TPosition) 0);
         SEQAN_ASSERT_EQ(traceSegment._length, (TSize) 0);
-        SEQAN_ASSERT_EQ(traceSegment._traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(traceSegment._traceValue, TraceBitMap_<>::NONE);
     }
 
     { // test copy ctor
@@ -58,30 +58,30 @@ testAlign2TracebackTraceSegmentsConstructor()
         traceSegment._horizontalBeginPos = 10;
         traceSegment._verticalBeginPos = 3;
         traceSegment._length = 5;
-        traceSegment._traceValue = +TraceBitMap_<>::DIAGONAL;
+        traceSegment._traceValue = TraceBitMap_<>::DIAGONAL;
 
         TTraceSegment traceSegment2(traceSegment);
 
         SEQAN_ASSERT_EQ(traceSegment2._horizontalBeginPos, (TPosition) 10);
         SEQAN_ASSERT_EQ(traceSegment2._verticalBeginPos, (TPosition) 3);
         SEQAN_ASSERT_EQ(traceSegment2._length, (TSize) 5);
-        SEQAN_ASSERT_EQ(traceSegment2._traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(traceSegment2._traceValue, TraceBitMap_<>::DIAGONAL);
 
         TTraceSegment traceSegment3 = traceSegment;
 
         SEQAN_ASSERT_EQ(traceSegment3._horizontalBeginPos, (TPosition) 10);
         SEQAN_ASSERT_EQ(traceSegment3._verticalBeginPos, (TPosition) 3);
         SEQAN_ASSERT_EQ(traceSegment3._length, (TSize) 5);
-        SEQAN_ASSERT_EQ(traceSegment3._traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(traceSegment3._traceValue, TraceBitMap_<>::DIAGONAL);
     }
 
     { // test additional ctor
-        TTraceSegment traceSegment(12, 13, 8, +TraceBitMap_<>::VERTICAL);
+        TTraceSegment traceSegment(12, 13, 8, TraceBitMap_<>::VERTICAL);
 
         SEQAN_ASSERT_EQ(traceSegment._horizontalBeginPos, (TPosition) 12);
         SEQAN_ASSERT_EQ(traceSegment._verticalBeginPos, (TPosition) 13);
         SEQAN_ASSERT_EQ(traceSegment._length, (TSize) 8);
-        SEQAN_ASSERT_EQ(traceSegment._traceValue, +TraceBitMap_<>::VERTICAL);
+        SEQAN_ASSERT_EQ(traceSegment._traceValue, TraceBitMap_<>::VERTICAL);
     }
 }
 
@@ -98,21 +98,21 @@ testAlign2TracebackTraceSegmentsAssignment()
         traceSegment._horizontalBeginPos = 10;
         traceSegment._verticalBeginPos = 3;
         traceSegment._length = 5;
-        traceSegment._traceValue = +TraceBitMap_<>::DIAGONAL;
+        traceSegment._traceValue = TraceBitMap_<>::DIAGONAL;
 
         TTraceSegment traceSegment2;
 
         SEQAN_ASSERT_EQ(traceSegment2._horizontalBeginPos, (TPosition) 0);
         SEQAN_ASSERT_EQ(traceSegment2._verticalBeginPos, (TPosition) 0);
         SEQAN_ASSERT_EQ(traceSegment2._length, (TSize) 0);
-        SEQAN_ASSERT_EQ(traceSegment2._traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(traceSegment2._traceValue, TraceBitMap_<>::NONE);
 
         traceSegment2 = traceSegment;
 
         SEQAN_ASSERT_EQ(traceSegment2._horizontalBeginPos, (TPosition) 10);
         SEQAN_ASSERT_EQ(traceSegment2._verticalBeginPos, (TPosition) 3);
         SEQAN_ASSERT_EQ(traceSegment2._length, (TSize) 5);
-        SEQAN_ASSERT_EQ(traceSegment2._traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(traceSegment2._traceValue, TraceBitMap_<>::DIAGONAL);
     }
 }
 
@@ -127,12 +127,12 @@ testAlign2TracebackTraceSegmentsCompare()
     traceSegment._horizontalBeginPos = 10;
     traceSegment._verticalBeginPos = 3;
     traceSegment._length = 5;
-    traceSegment._traceValue = +TraceBitMap_<>::DIAGONAL;
+    traceSegment._traceValue = TraceBitMap_<>::DIAGONAL;
 
     TTraceSegment traceSegment2(traceSegment);
 
     SEQAN_ASSERT(traceSegment2 == traceSegment);
-    traceSegment._traceValue = +TraceBitMap_<>::HORIZONTAL;
+    traceSegment._traceValue = TraceBitMap_<>::HORIZONTAL;
     SEQAN_ASSERT(traceSegment2 !=  traceSegment);
 }
 
@@ -171,26 +171,26 @@ void testAlign2TracebackRecordTrace(TTarget & target)
     _recordSegment(target, 0, 0, 3, tv1);
     _recordSegment(target, 0, 3, 5, tv2);
     _recordSegment(target, 5, 8, 3, tv3);
-    _recordSegment(target, 8, 8, 0, +TraceBitMap_<>::DIAGONAL);
+    _recordSegment(target, 8, 8, 0, TraceBitMap_<>::DIAGONAL);
 
 
 
     SEQAN_ASSERT_EQ(target[0]._horizontalBeginPos, 0);
     SEQAN_ASSERT_EQ(target[0]._verticalBeginPos, 0);
     SEQAN_ASSERT_EQ(target[0]._length, 3);
-    SEQAN_ASSERT_EQ(target[0]._traceValue, +TraceBitMap_<>::DIAGONAL);
+    SEQAN_ASSERT_EQ(target[0]._traceValue, TraceBitMap_<>::DIAGONAL);
     SEQAN_ASSERT_EQ(target[1]._horizontalBeginPos, 0);
     SEQAN_ASSERT_EQ(target[1]._verticalBeginPos, 3);
     SEQAN_ASSERT_EQ(target[1]._length, 5);
-    SEQAN_ASSERT_EQ(target[1]._traceValue, +TraceBitMap_<>::VERTICAL);
+    SEQAN_ASSERT_EQ(target[1]._traceValue, TraceBitMap_<>::VERTICAL);
     SEQAN_ASSERT_EQ(target[2]._horizontalBeginPos, 5);
     SEQAN_ASSERT_EQ(target[2]._verticalBeginPos, 8);
     SEQAN_ASSERT_EQ(target[2]._length, 3);
-    SEQAN_ASSERT_EQ(target[2]._traceValue, +TraceBitMap_<>::HORIZONTAL);
+    SEQAN_ASSERT_EQ(target[2]._traceValue, TraceBitMap_<>::HORIZONTAL);
 
     SEQAN_ASSERT_EQ(length(target), 3u);
 
-//    _recordSegment(target, 8, 8, 10, +TraceBitMap_<>::NONE); // note this should fail when uncommented
+//    _recordSegment(target, 8, 8, 10, TraceBitMap_<>::NONE); // note this should fail when uncommented
 }
 
 void testAlign2TraceAdaptorAdaptFile()
@@ -200,12 +200,12 @@ void testAlign2TraceAdaptorAdaptFile()
     typedef TraceSegment_<size_t, size_t> TTraceSegment;
     String<TTraceSegment> traceSegments;
 
-    appendValue(traceSegments, TTraceSegment(12, 8, 4, +TraceBitMap_<>::VERTICAL));
-    appendValue(traceSegments, TTraceSegment(8, 4, 4, +TraceBitMap_<>::DIAGONAL));
-    appendValue(traceSegments, TTraceSegment(8, 3, 1, +TraceBitMap_<>::VERTICAL));
-    appendValue(traceSegments, TTraceSegment(4, 3, 4, +TraceBitMap_<>::HORIZONTAL));
-    appendValue(traceSegments, TTraceSegment(1, 0, 3, +TraceBitMap_<>::DIAGONAL));
-    appendValue(traceSegments, TTraceSegment(0, 0, 1, +TraceBitMap_<>::HORIZONTAL));
+    appendValue(traceSegments, TTraceSegment(12, 8, 4, TraceBitMap_<>::VERTICAL));
+    appendValue(traceSegments, TTraceSegment(8, 4, 4, TraceBitMap_<>::DIAGONAL));
+    appendValue(traceSegments, TTraceSegment(8, 3, 1, TraceBitMap_<>::VERTICAL));
+    appendValue(traceSegments, TTraceSegment(4, 3, 4, TraceBitMap_<>::HORIZONTAL));
+    appendValue(traceSegments, TTraceSegment(1, 0, 3, TraceBitMap_<>::DIAGONAL));
+    appendValue(traceSegments, TTraceSegment(0, 0, 1, TraceBitMap_<>::HORIZONTAL));
 
     String<char> seq0 = "AAAACCCCGGGG";
     String<char> seq1 = "AAAACCCCGGGG";
@@ -272,12 +272,12 @@ void testAlign2TraceAdaptorAdaptAlign()
     typedef TraceSegment_<size_t, size_t> TTraceSegment;
     String<TTraceSegment> traceSegments;
 
-    appendValue(traceSegments, TTraceSegment(12, 8, 4, +TraceBitMap_<>::VERTICAL));
-    appendValue(traceSegments, TTraceSegment(8, 4, 4, +TraceBitMap_<>::DIAGONAL));
-    appendValue(traceSegments, TTraceSegment(8, 3, 1, +TraceBitMap_<>::VERTICAL));
-    appendValue(traceSegments, TTraceSegment(4, 3, 4, +TraceBitMap_<>::HORIZONTAL));
-    appendValue(traceSegments, TTraceSegment(1, 0, 3, +TraceBitMap_<>::DIAGONAL));
-    appendValue(traceSegments, TTraceSegment(0, 0, 1, +TraceBitMap_<>::HORIZONTAL));
+    appendValue(traceSegments, TTraceSegment(12, 8, 4, TraceBitMap_<>::VERTICAL));
+    appendValue(traceSegments, TTraceSegment(8, 4, 4, TraceBitMap_<>::DIAGONAL));
+    appendValue(traceSegments, TTraceSegment(8, 3, 1, TraceBitMap_<>::VERTICAL));
+    appendValue(traceSegments, TTraceSegment(4, 3, 4, TraceBitMap_<>::HORIZONTAL));
+    appendValue(traceSegments, TTraceSegment(1, 0, 3, TraceBitMap_<>::DIAGONAL));
+    appendValue(traceSegments, TTraceSegment(0, 0, 1, TraceBitMap_<>::HORIZONTAL));
 
     String<char> seq0 = "AAAACCCCGGGG";
     String<char> seq1 = "AAAACCCCGGGG";
@@ -316,12 +316,12 @@ void testAlign2TraceAdaptorAdaptFragments()
 
     String<TTraceSegment> traceSegments;
 
-    appendValue(traceSegments, TTraceSegment(12, 8, 4, +TraceBitMap_<>::VERTICAL));
-    appendValue(traceSegments, TTraceSegment(8, 4, 4, +TraceBitMap_<>::DIAGONAL));
-    appendValue(traceSegments, TTraceSegment(8, 3, 1, +TraceBitMap_<>::VERTICAL));
-    appendValue(traceSegments, TTraceSegment(4, 3, 4, +TraceBitMap_<>::HORIZONTAL));
-    appendValue(traceSegments, TTraceSegment(1, 0, 3, +TraceBitMap_<>::DIAGONAL));
-    appendValue(traceSegments, TTraceSegment(0, 0, 1, +TraceBitMap_<>::HORIZONTAL));
+    appendValue(traceSegments, TTraceSegment(12, 8, 4, TraceBitMap_<>::VERTICAL));
+    appendValue(traceSegments, TTraceSegment(8, 4, 4, TraceBitMap_<>::DIAGONAL));
+    appendValue(traceSegments, TTraceSegment(8, 3, 1, TraceBitMap_<>::VERTICAL));
+    appendValue(traceSegments, TTraceSegment(4, 3, 4, TraceBitMap_<>::HORIZONTAL));
+    appendValue(traceSegments, TTraceSegment(1, 0, 3, TraceBitMap_<>::DIAGONAL));
+    appendValue(traceSegments, TTraceSegment(0, 0, 1, TraceBitMap_<>::HORIZONTAL));
 
     _adaptTraceSegmentsTo(fragmentString, 0, 1, traceSegments);
 
@@ -344,12 +344,12 @@ void testAlign2TraceAdaptorAdaptAlignmentGraph()
 
     String<TTraceSegment> traceSegments;
 
-    appendValue(traceSegments, TTraceSegment(12, 8, 4, +TraceBitMap_<>::VERTICAL));
-    appendValue(traceSegments, TTraceSegment(8, 4, 4, +TraceBitMap_<>::DIAGONAL));
-    appendValue(traceSegments, TTraceSegment(8, 3, 1, +TraceBitMap_<>::VERTICAL));
-    appendValue(traceSegments, TTraceSegment(4, 3, 4, +TraceBitMap_<>::HORIZONTAL));
-    appendValue(traceSegments, TTraceSegment(1, 0, 3, +TraceBitMap_<>::DIAGONAL));
-    appendValue(traceSegments, TTraceSegment(0, 0, 1, +TraceBitMap_<>::HORIZONTAL));
+    appendValue(traceSegments, TTraceSegment(12, 8, 4, TraceBitMap_<>::VERTICAL));
+    appendValue(traceSegments, TTraceSegment(8, 4, 4, TraceBitMap_<>::DIAGONAL));
+    appendValue(traceSegments, TTraceSegment(8, 3, 1, TraceBitMap_<>::VERTICAL));
+    appendValue(traceSegments, TTraceSegment(4, 3, 4, TraceBitMap_<>::HORIZONTAL));
+    appendValue(traceSegments, TTraceSegment(1, 0, 3, TraceBitMap_<>::DIAGONAL));
+    appendValue(traceSegments, TTraceSegment(0, 0, 1, TraceBitMap_<>::HORIZONTAL));
 
     _adaptTraceSegmentsTo(alignGraph, 0, 1, traceSegments);
 
diff --git a/tests/align/test_alignment_dp_formula.h b/tests/align/test_alignment_dp_formula.h
index d4cae4c..7181a5d 100644
--- a/tests/align/test_alignment_dp_formula.h
+++ b/tests/align/test_alignment_dp_formula.h
@@ -62,7 +62,7 @@ void testDPFormulaNoTraceLocalLinearDiagonalDirection(TBand const &)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionDiagonal(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 4);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -71,7 +71,7 @@ void testDPFormulaNoTraceLocalLinearDiagonalDirection(TBand const &)
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                scoringScheme, RecursionDirectionDiagonal(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 0);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -101,7 +101,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -110,7 +110,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -121,7 +121,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                    scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -130,7 +130,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                    scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -159,20 +159,20 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_horizontal_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionHorizontal(), TDPProfileSingleTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
-    SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+    SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-    SEQAN_ASSERT_EQ(prevVertical._score, 10);
+    SEQAN_ASSERT_EQ(prevVertical._score, 6);
 
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
-    SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+    SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-    SEQAN_ASSERT_EQ(prevVertical._score, 10);
+    SEQAN_ASSERT_EQ(prevVertical._score, 6);
 }
 
 SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_vertical_direction)
@@ -196,14 +196,14 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_vertical_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
 
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
-    SEQAN_ASSERT_EQ(activeCell._score, 6);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+    SEQAN_ASSERT_EQ(activeCell._score, 2);
 }
 
 SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_upper_band_direction)
@@ -228,41 +228,43 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_upper_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
 
+        prevDiagonal._score = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
     }
 
     {
+        prevDiagonal._score = -10;
         prevHorizontal._score = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, -8);
 
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, -8);
     }
 
     {
@@ -270,20 +272,21 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_upper_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -4);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -4);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, -8);
 
+        prevDiagonal._score = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -4);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -4);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, -8);
     }
 }
 
@@ -309,7 +312,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -318,7 +321,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_lower_band_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -330,7 +333,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -339,7 +342,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_lower_band_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -351,7 +354,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -360,7 +363,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_lower_band_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -390,148 +393,174 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_linear_all_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::HORIZONTAL |
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL )|
                         TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
     }
 
     {
-        prevHorizontal._score = 0;
+        prevDiagonal._score = -10;
+        prevVertical._score = 5;
+        prevHorizontal._score = -5;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
-        SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
-        SEQAN_ASSERT_EQ(prevHorizontal._score, 0);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(activeCell._score, 1);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -5);
+        SEQAN_ASSERT_EQ(prevHorizontal._score, -5);
+        SEQAN_ASSERT_EQ(prevVertical._score, 1);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
-        SEQAN_ASSERT_EQ(prevHorizontal._score, 0);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -5);
+        SEQAN_ASSERT_EQ(prevHorizontal._score, -5);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
     }
 
     {
+        prevDiagonal._score = -10;
         prevVertical._score = -10;
+        prevHorizontal._score = 5;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
-        SEQAN_ASSERT_EQ(activeCell._score, -4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
-        SEQAN_ASSERT_EQ(prevHorizontal._score, 0);
-        SEQAN_ASSERT_EQ(prevVertical._score, -10);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(activeCell._score, 1);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 5);
+        SEQAN_ASSERT_EQ(prevHorizontal._score, 5);
+        SEQAN_ASSERT_EQ(prevVertical._score, 1);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
-        SEQAN_ASSERT_EQ(activeCell._score, -4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
-        SEQAN_ASSERT_EQ(prevHorizontal._score, 0);
-        SEQAN_ASSERT_EQ(prevVertical._score, -10);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(activeCell._score, 1);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 5);
+        SEQAN_ASSERT_EQ(prevHorizontal._score, 5);
+        SEQAN_ASSERT_EQ(prevVertical._score, 1);
     }
 
     {
+        prevDiagonal._score = 4;
+        prevVertical._score = 2;
         prevHorizontal._score = -4;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL));
-        SEQAN_ASSERT_EQ(activeCell._score, -8);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(activeCell._score, 6);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -4);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -4);
-        SEQAN_ASSERT_EQ(prevVertical._score, -10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
 
+        prevDiagonal._score = 4;
+        prevHorizontal._score = 10;
+        prevVertical._score = -4;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
-        SEQAN_ASSERT_EQ(activeCell._score, -8);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
-        SEQAN_ASSERT_EQ(prevHorizontal._score, -4);
-        SEQAN_ASSERT_EQ(prevVertical._score, -10);
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(activeCell._score, 6);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
     }
 
     {
+        prevDiagonal._score = 10;
+        prevVertical._score = 10;
         prevHorizontal._score = -12;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
-        SEQAN_ASSERT_EQ(activeCell._score, -8);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(activeCell._score, 12);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -12);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -12);
-        SEQAN_ASSERT_EQ(prevVertical._score, -10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
-        SEQAN_ASSERT_EQ(activeCell._score, -8);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(activeCell._score, 12);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -12);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -12);
-        SEQAN_ASSERT_EQ(prevVertical._score, -10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
-        prevVertical._score = -8;
+        prevDiagonal._score = 10;
+        prevVertical._score = 8;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL));
-        SEQAN_ASSERT_EQ(activeCell._score, -12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(activeCell._score, 8);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -12);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -12);
-        SEQAN_ASSERT_EQ(prevVertical._score, -8);
+        SEQAN_ASSERT_EQ(prevVertical._score, 8);
 
+        prevDiagonal._score = 10;
+        prevVertical._score = 12;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
-        SEQAN_ASSERT_EQ(activeCell._score, -12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(activeCell._score, 8);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -12);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -12);
-        SEQAN_ASSERT_EQ(prevVertical._score, -8);
+        SEQAN_ASSERT_EQ(prevVertical._score, 8);
     }
 
     {
-        prevHorizontal._score = -8;
+        prevDiagonal._score = 10;
+        prevVertical._score = 12;
+        prevHorizontal._score = 12;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL));
-        SEQAN_ASSERT_EQ(activeCell._score, -12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
-        SEQAN_ASSERT_EQ(prevHorizontal._score, -8);
-        SEQAN_ASSERT_EQ(prevVertical._score, -8);
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(activeCell._score, 8);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 12);
+        SEQAN_ASSERT_EQ(prevHorizontal._score, 12);
+        SEQAN_ASSERT_EQ(prevVertical._score, 8);
 
+        prevDiagonal._score = 10;
+        prevVertical._score = 12;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::HORIZONTAL |
-                                     TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
-        SEQAN_ASSERT_EQ(activeCell._score, -12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
-        SEQAN_ASSERT_EQ(prevHorizontal._score, -8);
-        SEQAN_ASSERT_EQ(prevVertical._score, -8);
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL |
+                                     TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(activeCell._score, 8);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 12);
+        SEQAN_ASSERT_EQ(prevHorizontal._score, 12);
+        SEQAN_ASSERT_EQ(prevVertical._score, 8);
     }
 }
 
@@ -563,7 +592,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_diagonal_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -572,7 +601,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -583,7 +612,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_diagonal_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -592,7 +621,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, -12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -611,15 +640,12 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_horizontal_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = -10;
-    prevDiagonal._verticalScore = -10;
     prevDiagonal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
-    prevHorizontal._verticalScore = -10;
     prevHorizontal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
-    prevVertical._verticalScore = -10;
     prevVertical._horizontalScore = -10;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
@@ -628,41 +654,53 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_horizontal_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
 
     {
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
         prevHorizontal._horizontalScore = 10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
 
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
     }
 }
 
@@ -677,16 +715,13 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_vertical_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = -10;
-    prevDiagonal._verticalScore = -10;
     prevDiagonal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
-    prevHorizontal._verticalScore = -10;
     prevHorizontal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
     prevVertical._verticalScore = -10;
-    prevVertical._horizontalScore = -10;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
 
@@ -694,41 +729,46 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_vertical_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
 
     {
+        prevVertical._score = 10;
         prevVertical._verticalScore = 10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
 
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
     }
 }
 
@@ -743,16 +783,13 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_upper_band_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = -10;
-    prevDiagonal._verticalScore = -10;
     prevDiagonal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
-    prevHorizontal._verticalScore = -10;
     prevHorizontal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
     prevVertical._verticalScore = -10;
-    prevVertical._horizontalScore = -10;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
 
@@ -760,128 +797,171 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_upper_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
 
     {
         prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         prevHorizontal._horizontalScore = 16;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         prevHorizontal._horizontalScore = 16;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL |
                                      TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         prevHorizontal._score = 18;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 18);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 18);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX |
-                                     +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::HORIZONTAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX |
+                                     TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 18);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 18);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         prevHorizontal._horizontalScore = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 18);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 18);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL_OPEN |
-                                     +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN |
+                                     TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 18);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 18);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 }
 
@@ -896,16 +976,13 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_lower_band_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = -10;
-    prevDiagonal._verticalScore = -10;
     prevDiagonal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
-    prevHorizontal._verticalScore = -10;
     prevHorizontal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
     prevVertical._verticalScore = -10;
-    prevVertical._horizontalScore = -10;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
 
@@ -913,16 +990,20 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 10);
 
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -931,19 +1012,26 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_lower_band_direction)
 
     {
         prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 10);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -951,20 +1039,27 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_lower_band_direction)
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
         prevVertical._verticalScore = 16;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 10);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 16;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -972,20 +1067,27 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_lower_band_direction)
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
         prevVertical._verticalScore = 16;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 10);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 16;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -993,21 +1095,28 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_lower_band_direction)
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
         prevVertical._score = 18;
+        prevVertical._verticalScore = 16;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 18);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
+        prevVertical._verticalScore = 16;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
-                                     +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::VERTICAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
+                                     TraceBitMap_<>::VERTICAL | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -1015,21 +1124,28 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_lower_band_direction)
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
         prevVertical._verticalScore = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 18);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL_OPEN |
-                                     +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN |
+                                     TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -1049,16 +1165,13 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_all_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = -10;
-    prevDiagonal._verticalScore = -10;
     prevDiagonal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = -10;
-    prevHorizontal._verticalScore = -10;
     prevHorizontal._horizontalScore = -10;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
     prevVertical._verticalScore = -10;
-    prevVertical._horizontalScore = -10;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
 
@@ -1066,282 +1179,340 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_affine_all_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
 
     {
         prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
         prevVertical._verticalScore = 16;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, -14);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 16;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, -14);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
         prevVertical._verticalScore = 16;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, -14);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 16;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL |
                                      TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, -14);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
         prevVertical._score = 18;
+        prevVertical._verticalScore = 16;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, -14);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 18);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
+        prevVertical._verticalScore = 16;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::VERTICAL_OPEN |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::VERTICAL_OPEN |
                                      TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, -14);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 18);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
         prevVertical._verticalScore = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL_OPEN |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN |
                                      TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, -14);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 18);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
 
+        prevDiagonal._score = 10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL_OPEN |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN |
                                      TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 12);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, -14);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 18);
+        SEQAN_ASSERT_EQ(prevVertical._score, 12);
     }
 
     {
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
+        prevVertical._verticalScore = -10;
         prevHorizontal._horizontalScore = 20;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::VERTICAL_OPEN |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL_OPEN |
                                      TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 18);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
 
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::VERTICAL_OPEN |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL_OPEN |
                                      TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, -10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, -10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 18);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
     }
 
     {
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
+        prevVertical._verticalScore = -10;
         prevHorizontal._score = 22;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | +TraceBitMap_<>::HORIZONTAL |
-                                     +TraceBitMap_<>::VERTICAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::HORIZONTAL |
+                                     TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 22);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 22);
-        SEQAN_ASSERT_EQ(prevVertical._score, 18);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
 
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 18;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | +TraceBitMap_<>::HORIZONTAL |
-                                     +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::HORIZONTAL |
+                                     TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 12);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 22);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 22);
-        SEQAN_ASSERT_EQ(prevVertical._score, 18);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
     }
 
     {
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
         prevVertical._score = 22;
+        prevVertical._verticalScore = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
                                      TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 16);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 22);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 22);
-        SEQAN_ASSERT_EQ(prevVertical._score, 22);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
 
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 22;
+        prevVertical._verticalScore = -10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
                                      TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 16);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 22);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 22);
-        SEQAN_ASSERT_EQ(prevVertical._score, 22);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
     }
 
     {
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 22;
         prevVertical._verticalScore = 20;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::VERTICAL |
-                                     +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL |
+                                     TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 16);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 22);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 22);
-        SEQAN_ASSERT_EQ(prevVertical._score, 22);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
 
+        prevDiagonal._score = -10;
+        prevDiagonal._horizontalScore = -10;
+        prevVertical._score = 22;
+        prevVertical._verticalScore = 20;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::VERTICAL |
-                                     +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL |
+                                     TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN |
                                      TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 16);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 22);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 22);
-        SEQAN_ASSERT_EQ(prevVertical._score, 22);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
     }
 
     {
         prevDiagonal._score = 14;
+        prevVertical._score = 22;
+        prevVertical._verticalScore = 20;
+        prevHorizontal._score = 22;
+        prevHorizontal._horizontalScore = 20;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 16);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 14);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 22);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 22);
-        SEQAN_ASSERT_EQ(prevVertical._score, 22);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
 
+        prevDiagonal._score = 14;
+        prevVertical._score = 22;
+        prevVertical._verticalScore = 20;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::VERTICAL |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL |
                                      TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::VERTICAL_OPEN |
                                      TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX |
                                      TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 16);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 16);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 16);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 14);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 22);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 22);
-        SEQAN_ASSERT_EQ(prevVertical._score, 22);
+        SEQAN_ASSERT_EQ(prevVertical._score, 16);
     }
 }
 
@@ -1367,7 +1538,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(_scoreOfCell(activeCell), -8);
         SEQAN_ASSERT_EQ(_scoreOfCell(prevDiagonal), -10);
         SEQAN_ASSERT_EQ(_scoreOfCell(prevHorizontal), 10);
@@ -1376,7 +1547,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(_scoreOfCell(activeCell), -8);
         SEQAN_ASSERT_EQ(_scoreOfCell(prevDiagonal), -10);
         SEQAN_ASSERT_EQ(_scoreOfCell(prevHorizontal), 10);
@@ -1387,7 +1558,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                    scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(_scoreOfCell(activeCell), -12);
         SEQAN_ASSERT_EQ(_scoreOfCell(prevDiagonal), -10);
         SEQAN_ASSERT_EQ(_scoreOfCell(prevHorizontal), 10);
@@ -1396,7 +1567,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                    scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(_scoreOfCell(activeCell), -12);
         SEQAN_ASSERT_EQ(_scoreOfCell(prevDiagonal), -10);
         SEQAN_ASSERT_EQ(_scoreOfCell(prevHorizontal), 10);
@@ -1426,7 +1597,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_horizontal_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionHorizontal(), TDPProfileSingleTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
     SEQAN_ASSERT_EQ(_scoreOfCell(activeCell), 6);
     SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
     SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
@@ -1434,7 +1605,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_horizontal_direction)
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                            scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
     SEQAN_ASSERT_EQ(_scoreOfCell(activeCell), 6);
     SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
     SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
@@ -1443,7 +1614,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_horizontal_direction)
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                            scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
     SEQAN_ASSERT_EQ(_scoreOfCell(activeCell), 8);
     SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
     SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
@@ -1471,20 +1642,25 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_vertical_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
 
+    prevDiagonal._score = -10;
+    prevVertical._score = 10;
+    _setBit(prevVertical, False(), DynamicGapExtensionVertical());
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
 
+    prevDiagonal._score = -10;
+    prevVertical._score = 10;
     _setBit(prevVertical, True(), DynamicGapExtensionVertical());
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
     SEQAN_ASSERT_EQ(activeCell._score, 8);
 }
 
@@ -1511,77 +1687,100 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_upper_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         _setBit(prevHorizontal, True(), DynamicGapExtensionHorizontal());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 8);
     }
 
     {
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         prevHorizontal._score = -10;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
     }
 
     {
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         prevHorizontal._score = -4;
         _setBit(prevHorizontal, False(), DynamicGapExtensionHorizontal());
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
+        _setBit(prevHorizontal, False(), DynamicGapExtensionVertical());
         prevHorizontal._score = -6;
         _setBit(prevHorizontal, True(), DynamicGapExtensionHorizontal());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                        scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
+        _setBit(prevHorizontal, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
+        prevDiagonal._score = -10;
+        prevVertical._score = 10;
+        _setBit(prevHorizontal, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
     }
 }
@@ -1609,20 +1808,20 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
 
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
 
         _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 8);
     }
 
@@ -1631,13 +1830,13 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
     }
 
@@ -1647,19 +1846,19 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
         prevVertical._score = -6;
@@ -1667,19 +1866,19 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_lower_band_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                        scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
     }
 }
@@ -1708,14 +1907,14 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_all_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
 
         // Complete trace.
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, -8);
     }
 
@@ -1725,61 +1924,79 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_all_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, -4);
 
         // Complete Trace + horizontal open.
+        prevDiagonal._score = -10;
+        prevVertical._score = -10;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, -4);
 
         // Single Trace + horizontal extend.
+        prevDiagonal._score = -10;
+        prevVertical._score = -10;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         _setBit(prevHorizontal, True(), DynamicGapExtensionHorizontal());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, -2);
 
         // Complete Trace + horizontal extend.
+        prevDiagonal._score = -10;
+        prevVertical._score = -10;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, -2);
     }
 
     {  // From vertical only.
         // Single Trace + vertical open.
+        prevDiagonal._score = -10;
         prevVertical._score = 4;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
 
-        // Complete Trace + horizontal open.
+        prevDiagonal._score = -10;
+        prevVertical._score = 4;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
 
         // Single Trace + horizontal extend.
+        prevDiagonal._score = -10;
+        prevVertical._score = 4;
         _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 2);
 
         // Complete Trace + horizontal extend.
+        prevDiagonal._score = -10;
+        prevVertical._score = 4;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 2);
     }
 
@@ -1787,39 +2004,50 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_all_direction)
         // Single trace + horizontal extend.
         prevHorizontal._score = 6;
         prevDiagonal._score = 2;
+        prevVertical._score = 4;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Complete trace + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 4;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Single Trace + horizontal open
+        prevDiagonal._score = 2;
+        prevVertical._score = 4;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         prevHorizontal._score = 8;
         _setBit(prevHorizontal, False(), DynamicGapExtensionHorizontal());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Complete trace + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 4;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
@@ -1827,80 +2055,99 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_all_direction)
 
     {  // From horziontal + vertical.
         // Single trace + vertical extend + horizontal open.
+        prevDiagonal._score = 2;
         prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Complete trace + vertical extend + horizontal open.
+        prevDiagonal._score = 2;
+        prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Single trace + vertical open + horizontal open.
-        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
+        prevDiagonal._score = 2;
         prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Complete trace + vertical open + horizontal open.
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Single trace + vertical open + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         _setBit(prevHorizontal, True(), DynamicGapExtensionHorizontal());
         prevHorizontal._score = 6;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Complete trace + vertical open + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Single trace + vertical extend + horizontal extend.
-        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
+        prevDiagonal._score = 2;
         prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Complete trace + vertical extend + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'C',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
@@ -1910,39 +2157,48 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_all_direction)
         // Single trace + vertical extend.
         prevHorizontal._score = 0;
         prevDiagonal._score = 2;
+        prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Complete trace + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Single Trace + vertical open
+        prevDiagonal._score = 2;
         prevVertical._score = 8;
         _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Complete trace + vertical extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
@@ -1951,19 +2207,25 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_all_direction)
     {  // From horizontal + vertical + diagonal.
         // Single trace + vertical open + horizontal extend.
         prevHorizontal._score = 6;
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Complete trace + vertical open + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
@@ -1971,59 +2233,75 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_global_dynamic_all_direction)
         // Single trace + vertical open + horizontal open.
         _setBit(prevHorizontal, False(), DynamicGapExtensionHorizontal());
         prevHorizontal._score = 8;
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Complete trace + vertical open + horizontal open.
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
+        _setBit(prevVertical, False(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Single trace + vertical extend + horizontal open.
-        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
+        prevDiagonal._score = 2;
         prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Complete trace + vertical open + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
 
         // Single trace + vertical extend + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         _setBit(prevHorizontal, True(), DynamicGapExtensionHorizontal());
         prevHorizontal._score = 6;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), false);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), false);
 
         // Complete trace + vertical extend + horizontal extend.
+        prevDiagonal._score = 2;
+        prevVertical._score = 6;
+        _setBit(prevVertical, True(), DynamicGapExtensionVertical());
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionHorizontal()), true);
         SEQAN_ASSERT_EQ(isGapExtension(activeCell, DynamicGapExtensionVertical()), true);
@@ -2051,7 +2329,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_diagonal_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
     SEQAN_ASSERT_EQ(activeCell._score, 4);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -2060,7 +2338,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_diagonal_direction)
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
     SEQAN_ASSERT_EQ(activeCell._score, 4);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -2069,16 +2347,17 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_diagonal_direction)
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 0);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
     SEQAN_ASSERT_EQ(prevVertical._score, 10);
 
+    prevVertical._score = 10;
     traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
     SEQAN_ASSERT_EQ(activeCell._score, 0);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -2107,40 +2386,46 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_horizontal_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
     }
     {
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
         prevHorizontal._score = 2;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
     }
 }
 SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_vertical_direction)
@@ -2165,40 +2450,45 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_vertical_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 6);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 6);
     }
     {
+        prevDiagonal._score = 2;
         prevVertical._score = 2;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 2);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 2;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 2);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
     }
 }
 SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_upper_band_direction)
@@ -2223,42 +2513,49 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_upper_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 8);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 8);
-        SEQAN_ASSERT_EQ(prevVertical._score, 2);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 2;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 8);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 8);
-        SEQAN_ASSERT_EQ(prevVertical._score, 2);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
     {
         prevHorizontal._score = 2;
+        prevDiagonal._score = 2;
+        prevVertical._score = 2;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
-        SEQAN_ASSERT_EQ(prevVertical._score, 2);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 2;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
-        SEQAN_ASSERT_EQ(prevVertical._score, 2);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
     }
 }
+
 SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_lower_band_direction)
 {
     using namespace seqan;
@@ -2281,7 +2578,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
@@ -2290,27 +2587,30 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_lower_band_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
         SEQAN_ASSERT_EQ(prevVertical._score, 8);
     }
     {
+        prevDiagonal._score = 2;
         prevVertical._score = 2;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
         SEQAN_ASSERT_EQ(prevVertical._score, 2);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 2;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
@@ -2340,21 +2640,23 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_all_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 8);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 8);
-        SEQAN_ASSERT_EQ(prevVertical._score, 8);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 8;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::VERTICAL |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL |
                                      TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 8);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 8);
-        SEQAN_ASSERT_EQ(prevVertical._score, 8);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
     {
         prevDiagonal._score = 0;
@@ -2363,20 +2665,22 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_linear_all_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 0);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
-        SEQAN_ASSERT_EQ(prevVertical._score, 2);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
 
+        prevDiagonal._score = 0;
+        prevVertical._score = 2;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 0);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 2);
-        SEQAN_ASSERT_EQ(prevVertical._score, 2);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
     }
 }
 
@@ -2391,15 +2695,11 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_diagonal_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = 2;
-    prevDiagonal._horizontalScore = 4;
-    prevDiagonal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
     prevHorizontal._horizontalScore = 4;
-    prevHorizontal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
-    prevVertical._horizontalScore = 4;
     prevVertical._verticalScore = 4;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
@@ -2409,7 +2709,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_diagonal_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(activeCell._verticalScore, inf);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
@@ -2420,7 +2720,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_diagonal_direction)
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(activeCell._verticalScore, inf);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
@@ -2431,31 +2731,32 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_diagonal_direction)
 
 
     {
-        prevDiagonal._horizontalScore = 2;
-        prevDiagonal._verticalScore = 2;
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 4;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 10);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 4;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 10);
     }
-
 }
 
 SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_horizontal_direction)
@@ -2469,68 +2770,68 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_horizontal_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = 2;
-    prevDiagonal._horizontalScore = 4;
-    prevDiagonal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
     prevHorizontal._horizontalScore = 8;
-    prevHorizontal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
-    prevVertical._horizontalScore = 4;
     prevVertical._verticalScore = 4;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
-    int inf = DPCellDefaultInfinity<DPCell_<int, AffineGaps> >::VALUE;
 
     {
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, inf);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 4;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::HORIZONTAL_OPEN | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, inf);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
 
     {
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 4;
         prevHorizontal._score = 1;
         prevHorizontal._horizontalScore = 1;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, -3);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 1);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 1);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 4;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionHorizontal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, -3);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 1);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 1);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
     }
 }
 
@@ -2545,15 +2846,11 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_vertical_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = 2;
-    prevDiagonal._horizontalScore = 4;
-    prevDiagonal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
     prevHorizontal._horizontalScore = 8;
-    prevHorizontal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
-    prevVertical._horizontalScore = 4;
     prevVertical._verticalScore = 8;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
@@ -2563,50 +2860,53 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_vertical_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 4);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 8;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL | TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 4);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
 
     {
+        prevDiagonal._score = 2;
         prevVertical._score = 1;
         prevVertical._verticalScore = 1;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 1);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 1;
+        prevVertical._verticalScore = 1;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionVertical(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 1);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
     }
 }
 
@@ -2621,69 +2921,69 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_upper_band_direction)
     DPCell_<int, AffineGaps> activeCell;
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = 2;
-    prevDiagonal._horizontalScore = 4;
-    prevDiagonal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
     prevHorizontal._horizontalScore = 8;
-    prevHorizontal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
-    prevVertical._horizontalScore = 4;
     prevVertical._verticalScore = 8;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
-    int inf = DPCellDefaultInfinity<DPCell_<int, AffineGaps> >::VALUE;
 
     {
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 4);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, inf);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 8;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX |
-                                     +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX |
+                                     TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 4);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, inf);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
 
     {
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 8;
         prevHorizontal._score = 1;
         prevHorizontal._horizontalScore = 1;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, -3);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 1);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 1);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 8;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                    scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, -3);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 1);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 1);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 0);
     }
 }
 
@@ -2699,14 +2999,11 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_lower_band_direction)
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = 2;
     prevDiagonal._horizontalScore = 4;
-    prevDiagonal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
     prevHorizontal._horizontalScore = 8;
-    prevHorizontal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
-    prevVertical._horizontalScore = 4;
     prevVertical._verticalScore = 8;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
@@ -2716,48 +3013,51 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_lower_band_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL | TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL | TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 10);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 8;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
-                                     +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
+                                     TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 4);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 10);
     }
 
     {
+        prevDiagonal._score = 2;
         prevVertical._score = 1;
         prevVertical._verticalScore = 1;
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 1);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 1;
+        prevVertical._verticalScore = 1;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                    scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
-        SEQAN_ASSERT_EQ(activeCell._horizontalScore, 0);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 0);
+        SEQAN_ASSERT_EQ(activeCell._horizontalScore, inf);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
         SEQAN_ASSERT_EQ(prevVertical._score, 1);
@@ -2776,14 +3076,11 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_all_direction)
     DPCell_<int, AffineGaps> prevDiagonal;
     prevDiagonal._score = 2;
     prevDiagonal._horizontalScore = 4;
-    prevDiagonal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevHorizontal;
     prevHorizontal._score = 10;
     prevHorizontal._horizontalScore = 8;
-    prevHorizontal._verticalScore = 4;
     DPCell_<int, AffineGaps> prevVertical;
     prevVertical._score = 10;
-    prevVertical._horizontalScore = 4;
     prevVertical._verticalScore = 8;
 
     Score<int, Simple> scoringScheme(2, -2, -4, -6);
@@ -2792,30 +3089,32 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_all_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                                scoringScheme, RecursionDirectionAll(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::DIAGONAL));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 4);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 10;
+        prevVertical._verticalScore = 8;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                    scoringScheme, RecursionDirectionAll(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, (+TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX |
-                                     +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
-                                     +TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN |
+        SEQAN_ASSERT_EQ(traceValue, (TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX |
+                                     TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX |
+                                     TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::HORIZONTAL_OPEN |
                                      TraceBitMap_<>::VERTICAL_OPEN));
         SEQAN_ASSERT_EQ(activeCell._score, 4);
         SEQAN_ASSERT_EQ(activeCell._horizontalScore, 4);
-        SEQAN_ASSERT_EQ(activeCell._verticalScore, 4);
-        SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+        SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-        SEQAN_ASSERT_EQ(prevVertical._score, 10);
+        SEQAN_ASSERT_EQ(prevVertical._score, 4);
     }
 
     {
+        prevDiagonal._score = 2;
         prevHorizontal._score = 1;
         prevHorizontal._horizontalScore = 1;
         prevVertical._score = 1;
@@ -2823,16 +3122,19 @@ SEQAN_DEFINE_TEST(test_dp_formula_trace_local_affine_all_direction)
         TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileSingleTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 1);
         SEQAN_ASSERT_EQ(prevVertical._score, 1);
 
+        prevDiagonal._score = 2;
+        prevVertical._score = 1;
+        prevVertical._verticalScore = 1;
         traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'C', 'A',
                                                scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfileCompleteTrace());
 
-        SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL));
         SEQAN_ASSERT_EQ(activeCell._score, 0);
         SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
         SEQAN_ASSERT_EQ(prevHorizontal._score, 1);
@@ -2860,7 +3162,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_notrace_diagonal_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionDiagonal(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 4);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -2887,11 +3189,11 @@ SEQAN_DEFINE_TEST(test_dp_formula_notrace_horizontal_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionHorizontal(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
-    SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
+    SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-    SEQAN_ASSERT_EQ(prevVertical._score, 10);
+    SEQAN_ASSERT_EQ(prevVertical._score, 6);
 }
 
 SEQAN_DEFINE_TEST(test_dp_formula_notrace_vertical_direction)
@@ -2914,11 +3216,11 @@ SEQAN_DEFINE_TEST(test_dp_formula_notrace_vertical_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionVertical(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 2);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-    SEQAN_ASSERT_EQ(prevVertical._score, 10);
+    SEQAN_ASSERT_EQ(prevVertical._score, 6);
 }
 
 SEQAN_DEFINE_TEST(test_dp_formula_notrace_upper_band_direction)
@@ -2941,11 +3243,11 @@ SEQAN_DEFINE_TEST(test_dp_formula_notrace_upper_band_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionUpperDiagonal(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
-    SEQAN_ASSERT_EQ(prevDiagonal._score, 4);
+    SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-    SEQAN_ASSERT_EQ(prevVertical._score, 10);
+    SEQAN_ASSERT_EQ(prevVertical._score, 6);
 }
 
 SEQAN_DEFINE_TEST(test_dp_formula_notrace_lower_band_direction)
@@ -2968,7 +3270,7 @@ SEQAN_DEFINE_TEST(test_dp_formula_notrace_lower_band_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionLowerDiagonal(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
     SEQAN_ASSERT_EQ(prevDiagonal._score, 4);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
@@ -2995,11 +3297,11 @@ SEQAN_DEFINE_TEST(test_dp_formula_notrace_all_direction)
     TTraceValue traceValue = _computeScore(activeCell, prevDiagonal, prevHorizontal, prevVertical, 'A', 'A',
                                            scoringScheme, RecursionDirectionAll(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(traceValue, +TraceBitMap_<>::NONE);
+    SEQAN_ASSERT_EQ(static_cast<int>(traceValue), static_cast<int>(TraceBitMap_<>::NONE));
     SEQAN_ASSERT_EQ(activeCell._score, 6);
-    SEQAN_ASSERT_EQ(prevDiagonal._score, 4);
+    SEQAN_ASSERT_EQ(prevDiagonal._score, 10);
     SEQAN_ASSERT_EQ(prevHorizontal._score, 10);
-    SEQAN_ASSERT_EQ(prevVertical._score, 10);
+    SEQAN_ASSERT_EQ(prevVertical._score, 6);
 }
 
 
diff --git a/tests/align/test_alignment_dp_matrix.h b/tests/align/test_alignment_dp_matrix.h
index eddb95c..9ddbf89 100644
--- a/tests/align/test_alignment_dp_matrix.h
+++ b/tests/align/test_alignment_dp_matrix.h
@@ -294,7 +294,7 @@ void testAlignmentDPMatrixGetValueMF(TSpec const &)
     typedef DPMatrix_<int, TSpec> TDPMatrix;
     typedef DPMatrix_<int, TSpec> const TDPMatrixConst;
 
-    bool result = IsSameType<typename GetValue<TDPMatrix>::Type, int &>::VALUE;
+    bool result = IsSameType<typename GetValue<TDPMatrix>::Type, int const &>::VALUE;
     bool result2 = IsSameType<typename GetValue<TDPMatrixConst>::Type, int const &>::VALUE;
 
     SEQAN_ASSERT_EQ(result, true);
diff --git a/tests/align/test_alignment_dp_matrix_navigator.h b/tests/align/test_alignment_dp_matrix_navigator.h
index 9172cea..5c57c97 100644
--- a/tests/align/test_alignment_dp_matrix_navigator.h
+++ b/tests/align/test_alignment_dp_matrix_navigator.h
@@ -35,50 +35,18 @@
 #ifndef SANDBOX_RMAERKER_TESTS_ALIGN2_TEST_ALIGNMENT_DP_MATRIX_NAVIGATOR_H_
 #define SANDBOX_RMAERKER_TESTS_ALIGN2_TEST_ALIGNMENT_DP_MATRIX_NAVIGATOR_H_
 
-#include <seqan/basic.h>
+#include <algorithm>
 
+#include <seqan/basic.h>
 #include <seqan/align.h>
 
 
 template <typename TSpec>
-void testAlignmentDPMatrixScoreNavigatorConstructorDefault(TSpec const &)
-{
-    using namespace seqan;
-
-    typedef DPMatrix_<int, TSpec> TDPMatrix;
-    typedef typename Value<TDPMatrix>::Type TDPCell;
-    typedef typename Iterator<TDPMatrix, Standard>::Type TIterator;
-
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
-    // Test if default constructor sets NULL pointer
-    bool resultPointer = true;
-    if (dpScoreMatrixNavigator._ptrDataContainer)
-        resultPointer = false;
-
-    bool resultPrevColIter = true;
-    if (dpScoreMatrixNavigator._prevColIterator != TIterator())
-        resultPrevColIter = false;
-
-    bool resultActiveColIter = true;
-    if (dpScoreMatrixNavigator._activeColIterator != TIterator())
-        resultActiveColIter = false;
-
-    SEQAN_ASSERT_EQ(resultPointer, true);
-    SEQAN_ASSERT_EQ(resultPrevColIter, true);
-    SEQAN_ASSERT_EQ(resultActiveColIter, true);
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 0);
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
-}
-
-template <typename TSpec>
 void testAlignmentDPMatrixTraceNavigatorConstructorDefault(TSpec const &)
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, FullDPMatrix> TDPMatrix;
     typedef typename Iterator<TDPMatrix, Standard>::Type TIterator;
 
     DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TSpec>, NavigateColumnWise> dpTraceMatrixNavigator;
@@ -97,116 +65,70 @@ void testAlignmentDPMatrixTraceNavigatorConstructorDefault(TSpec const &)
     SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 0);
 }
 
-void testAlignmentDPMatrixNavigatorScoreMarixSparseContructor()
-{
-    using namespace seqan;
-
-    typedef DPMatrix_<int, SparseDPMatrix> TDPMatrix;
-    typedef Value<TDPMatrix>::Type TDPCell;
-    typedef Iterator<TDPMatrix, Standard>::Type TIterator;
-
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
-    // Test if default constructor sets NULL pointer
-    bool resultPointer = true;
-    if (dpScoreMatrixNavigator._ptrDataContainer)
-        resultPointer = false;
-
-    bool resultActiveColIter = true;
-    if (dpScoreMatrixNavigator._activeColIterator != TIterator())
-        resultActiveColIter = false;
-
-    bool resultPrevColIter = true;
-    if (dpScoreMatrixNavigator._prevColIterator != TIterator())
-        resultPrevColIter = false;
-
-    SEQAN_ASSERT_EQ(resultPointer, true);
-    SEQAN_ASSERT_EQ(resultActiveColIter, true);
-    SEQAN_ASSERT_EQ(resultPrevColIter, true);
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 0);
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
-}
-
-
 void testAlignmentDPMatrixNavigatorScoreMarixInitUnbanded()
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, FullDPMatrix> TDPMatrix;
     typedef Value<TDPMatrix>::Type TDPCell;
 
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 0);
+    resize(dpMatrix, TDPCell{});
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
     SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
     SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -10);
     SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
 }
 
 void testAlignmentDPMatrixNavigatorScoreMarixSparseInitUnbanded()
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, SparseDPMatrix> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, SparseDPMatrix> TDPMatrix;
     typedef Value<TDPMatrix>::Type TDPCell;
     typedef DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> TDPMatrixNavigator;
 
-    TDPMatrixNavigator dpScoreMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 0);
+    resize(dpMatrix, TDPCell{});
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    TDPMatrixNavigator dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
     SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
     SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
     SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-    SEQAN_ASSERT_EQ(value(dpScoreMatrixNavigator._activeColIterator), 0);
-    SEQAN_ASSERT_EQ(value(dpScoreMatrixNavigator._prevColIterator), 0);
+    SEQAN_ASSERT_EQ(value(dpScoreMatrixNavigator._activeColIterator), TDPCell{});
+    SEQAN_ASSERT_EQ(value(dpScoreMatrixNavigator._prevColIterator), TDPCell{});
     SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -9);
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
 }
 
 void testAlignmentDPMatrixNavigatorScoreMarixInitBanded()
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, FullDPMatrix> TDPMatrix;
     typedef Value<TDPMatrix>::Type TDPCell;
-    typedef DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> TDPMatrixNavigator;
+    typedef DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWiseBanded> TDPMatrixNavigator;
 
-    TDPMatrixNavigator dpScoreMatrixNavigator;
 
     { // Case1: Band intersects with poit of origin.
         TDPMatrix dpMatrix;
         setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
         setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 8);
-        resize(dpMatrix, 0);
+        resize(dpMatrix, TDPCell{});
 
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOn>(-4, 3));
+        TDPMatrixNavigator dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOn>{-4, 3}};
 
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -5);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
     }
 
     {
@@ -216,15 +138,13 @@ void testAlignmentDPMatrixNavigatorScoreMarixInitBanded()
         resize(dpMatrix2);
 
         value(host(dpMatrix2), 0) = 10;
-        _init(dpScoreMatrixNavigator, dpMatrix2, DPBandConfig<BandOn>(0, 7));
+
+        TDPMatrixNavigator dpScoreMatrixNavigator{dpMatrix2, DPBandConfig<BandOn>{0, 7}};
 
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix2);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix2, Standard()), 7);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix2, Standard()), -1);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 8);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
     }
 
     {
@@ -233,45 +153,35 @@ void testAlignmentDPMatrixNavigatorScoreMarixInitBanded()
         setLength(dpMatrix3, DPMatrixDimension_::VERTICAL, 8);
         resize(dpMatrix3);
 
-
-        _init(dpScoreMatrixNavigator, dpMatrix3, DPBandConfig<BandOn>(-7, 0));
+        TDPMatrixNavigator dpScoreMatrixNavigator{dpMatrix3, DPBandConfig<BandOn>{-7, 0}};
 
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix3);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix3, Standard()), 0);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix3, Standard()), -8);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
     }
-
 }
 
 void testAlignmentDPMatrixNavigatorScoreMarixSparseInitBanded()
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, SparseDPMatrix> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, SparseDPMatrix> TDPMatrix;
     typedef Value<TDPMatrix>::Type TDPCell;
-    typedef DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> TDPMatrixNavigator;
-
-    TDPMatrixNavigator dpScoreMatrixNavigator;
+    typedef DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWiseBanded> TDPMatrixNavigator;
 
     {
         TDPMatrix dpMatrix;
         setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
         setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 8);
-        resize(dpMatrix, 0);
+        resize(dpMatrix, TDPCell{});
 
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOn>(-4, 3));
+        TDPMatrixNavigator dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOn>{-4, 3}};
 
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 3);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
     }
 
     {
@@ -280,15 +190,12 @@ void testAlignmentDPMatrixNavigatorScoreMarixSparseInitBanded()
         setLength(dpMatrix2, DPMatrixDimension_::VERTICAL, 8);
         resize(dpMatrix2);
 
-        _init(dpScoreMatrixNavigator, dpMatrix2, DPBandConfig<BandOn>(0, 7));
+        TDPMatrixNavigator dpScoreMatrixNavigator{dpMatrix2, DPBandConfig<BandOn>{0, 7}};
 
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix2);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix2, Standard()), 7);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix2, Standard()), 7);  // Behind the last cell.
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
     }
 
     {
@@ -297,15 +204,12 @@ void testAlignmentDPMatrixNavigatorScoreMarixSparseInitBanded()
         setLength(dpMatrix3, DPMatrixDimension_::VERTICAL, 8);
         resize(dpMatrix3);
 
-        _init(dpScoreMatrixNavigator, dpMatrix3, DPBandConfig<BandOn>(-7, 0));
+        TDPMatrixNavigator dpScoreMatrixNavigator{dpMatrix3, DPBandConfig<BandOn>{-7, 0}};
 
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix3);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix3, Standard()), 0);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix3, Standard()), 0);
         SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -7);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
     }
 }
 
@@ -313,846 +217,140 @@ void testAlignmentDPMatrixNavigatorScoreMarixGoNextCell()
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, FullDPMatrix> TDPMatrix;
     typedef Value<TDPMatrix>::Type TDPCell;
 
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
     TDPMatrix dpMatrix;
-    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
-    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 3);
-    resize(dpMatrix, 0);
-    host(dpMatrix)[0] = 0;
-    host(dpMatrix)[1] = 1;
-    host(dpMatrix)[2] = 2;
-    host(dpMatrix)[3] = 3;
-    host(dpMatrix)[4] = 4;
-    host(dpMatrix)[5] = 5;
+    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 4);
+    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 4);
+    resize(dpMatrix, TDPCell{});
 
+    int score = 0;
+    auto generator = [&score]()
     {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
+        TDPCell cell;
+        cell = score++;
+        return cell;
+    };
 
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
+    std::generate(begin(host(dpMatrix), Standard()), end(host(dpMatrix), Standard()), generator);
 
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-    }
+    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        navi{dpMatrix, DPBandConfig<BandOff>{}};
 
+    // Initialize with 0.
+    _setScoreOfCell(value(navi), 0);
+    // Move along initial column.
+    _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, FirstCell{});
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 0);
+    for (int v_pos = 1; v_pos < 3; ++v_pos)
     {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
+        _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, InnerCell{});
+        SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), v_pos);
     }
+    _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, LastCell{});
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 3);
 
+    // Move along inner columns.
+    for (int h_pos = 1; h_pos < 3; ++h_pos)
     {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
+        _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, FirstCell{});
+        SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), h_pos * 4);
+        SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), (h_pos - 1) * 4);
+        for (int v_pos = 1; v_pos < 3; ++v_pos)
+        {
+            _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, InnerCell{});
+            SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), h_pos * 4 + v_pos);
+            SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), (h_pos - 1) * 4 + v_pos);
+        }
+        _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, LastCell{});
+        SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), h_pos * 4 + 3);
+        SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), (h_pos - 1) * 4 + 3);
     }
 
+    // Move along last column.
+    _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, FirstCell{});
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 12);
+    SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), 8);
+    for (int v_pos = 1; v_pos < 3; ++v_pos)
     {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), -1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpScoreMatrixNavigator._activeColIterator += 2;
-        dpScoreMatrixNavigator._prevColIterator += 2;
-        ++dpScoreMatrixNavigator._laneLeap;  // For the test we simulate as if we were in a band.
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpScoreMatrixNavigator._activeColIterator += 2;
-        dpScoreMatrixNavigator._prevColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpScoreMatrixNavigator._activeColIterator += 2;
-        dpScoreMatrixNavigator._prevColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 2);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpScoreMatrixNavigator._activeColIterator += 2;
-        dpScoreMatrixNavigator._prevColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpScoreMatrixNavigator._activeColIterator += 2;
-        dpScoreMatrixNavigator._prevColIterator += 2;
-        ++dpScoreMatrixNavigator._laneLeap;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpScoreMatrixNavigator._activeColIterator += 2;
-        dpScoreMatrixNavigator._prevColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpScoreMatrixNavigator._activeColIterator += 2;
-        dpScoreMatrixNavigator._prevColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 2);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpScoreMatrixNavigator._activeColIterator += 2;
-        dpScoreMatrixNavigator._prevColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 4);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, 1);
+        _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, InnerCell{});
+        SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 12 + v_pos);
+        SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), 8 + v_pos);
     }
+    _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, LastCell{});
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 15);
+    SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), 11);
 }
 
-void testAlignmentDPMatrixNavigatorScoreMarixSparseGoNext()
+void testAlignmentDPMatrixNavigatorScoreMarixSparseGoNextCell()
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, SparseDPMatrix> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, SparseDPMatrix> TDPMatrix;
     typedef Value<TDPMatrix>::Type TDPCell;
 
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
     TDPMatrix dpMatrix;
-    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 3);
-    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 3);
-    resize(dpMatrix, 3);
-
-    host(dpMatrix)[1] = 1;
-    host(dpMatrix)[2] = 2;
+    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 4);
+    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 4);
+    resize(dpMatrix, TDPCell{});
 
+    int score = 0;
+    auto generator = [&score]()
     {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
+        TDPCell cell;
+        cell = score++;
+        return cell;
+    };
 
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
+    std::generate(begin(host(dpMatrix), Standard()), end(host(dpMatrix), Standard()), generator);
 
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);     // Was never set to 0.
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
+    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        navi{dpMatrix, DPBandConfig<BandOff>()};
 
+    // Initialize with 0.
+    _setScoreOfCell(value(navi), 0);
+    // Move along initial column.
+    _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, FirstCell{});
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 0);
+    for (int v_pos = 1; v_pos < 3; ++v_pos)
     {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
-
-    {
-
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        // Need to update iterator just for the test.
-        dpScoreMatrixNavigator._activeColIterator += 3;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        // Need to update Iterator just for the test.
-        dpScoreMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        // Need to update Iterator just for the test.
-        dpScoreMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        // Need to set iterator to correct position just for the test.
-        --dpScoreMatrixNavigator._prevColIterator;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), LastCell());
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        dpScoreMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        dpScoreMatrixNavigator._activeColIterator += 3;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -3);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
+        _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, InnerCell{});
+        SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), v_pos);
     }
+    _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, LastCell{});
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 3);
 
+    // Move along inner columns.
+    for (int h_pos = 1; h_pos < 3; ++h_pos)
     {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        dpScoreMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
+        _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, FirstCell{});
+        SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 0);
+        SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), 0);
+        for (int v_pos = 1; v_pos < 3; ++v_pos)
+        {
+            _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, InnerCell{});
+            SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), v_pos);
+            SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), v_pos);
+        }
+        _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, LastCell{});
+        SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 3);
+        SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), 3);
     }
 
+    // Move along last column.
+    _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, FirstCell{});
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 0);
+    SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), 0);
+    for (int v_pos = 1; v_pos < 3; ++v_pos)
     {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        dpScoreMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        --dpScoreMatrixNavigator._prevColIterator;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-    }
-
-    {
-        _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        *dpScoreMatrixNavigator._activeColIterator = 0;
-
-        dpScoreMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), FirstCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), InnerCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 0);
-
-        _goNextCell(dpScoreMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), LastCell());
-
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._ptrDataContainer, &dpMatrix);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._laneLeap, -2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, 1);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, 2);
-        SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, 1);
+        _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, InnerCell{});
+        SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), v_pos);
+        SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), v_pos);
     }
+    _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, LastCell{});
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(navi)), 3);
+    SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(navi)), 3);
 }
 
 template <typename TDPMatrixSpec>
@@ -1160,19 +358,21 @@ void testAlignmentDPScoreMatrixNavigatorAssignValue(TDPMatrixSpec const)
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, TDPMatrixSpec> TDPMatrix;
-
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, TDPMatrixSpec> TDPMatrix;
+    typedef typename Value<TDPMatrix>::Type TDPCell;
 
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 3);
+    resize(dpMatrix, TDPCell{});
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
+    TDPCell tmp;
+    tmp = 20;
 
-    assignValue(dpScoreMatrixNavigator, 20);
-    SEQAN_ASSERT_EQ(value(dpScoreMatrixNavigator._activeColIterator), 20);
+    assignValue(dpScoreMatrixNavigator, tmp);
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(dpScoreMatrixNavigator._activeColIterator)), 20);
 }
 
 template <typename TDPMatrixSpec>
@@ -1180,97 +380,52 @@ void testAlignmentDPScoreMatrixNavigatorValue(TDPMatrixSpec const)
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, TDPMatrixSpec> TDPMatrix;
-
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
-    TDPMatrix dpMatrix;
-    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
-    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 3);
-
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-    assignValue(dpScoreMatrixNavigator, 20);
-    SEQAN_ASSERT_EQ(value(dpScoreMatrixNavigator), 20);
-
-    const DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigatorConst(dpScoreMatrixNavigator);
-    SEQAN_ASSERT_EQ(value(dpScoreMatrixNavigatorConst), 20);
-}
-
-template <typename TDPMatrixSpec>
-void testAlignmentDPScoreMatrixNavigatorPreviousCellDiagonal(TDPMatrixSpec const)
-{
-    using namespace seqan;
-
-    typedef DPMatrix_<int, TDPMatrixSpec> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, TDPMatrixSpec> TDPMatrix;
     typedef typename Value<TDPMatrix>::Type TDPCell;
 
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 3);
+    resize(dpMatrix, TDPCell{});
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellDiagonal, TDPCell());
+    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
-    dpScoreMatrixNavigator._prevCellDiagonal = 20;
-    SEQAN_ASSERT_EQ(previousCellDiagonal(dpScoreMatrixNavigator), 20);
+    TDPCell tmp;
+    tmp = 20;
 
-    const DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigatorConst(dpScoreMatrixNavigator);
-    SEQAN_ASSERT_EQ(previousCellDiagonal(dpScoreMatrixNavigatorConst), 20);
-}
+    assignValue(dpScoreMatrixNavigator, tmp);
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(dpScoreMatrixNavigator)), 20);
 
-template <typename TDPMatrixSpec>
-void testAlignmentDPScoreMatrixNavigatorPreviousCellHorizontal(TDPMatrixSpec const)
-{
-    using namespace seqan;
-
-    typedef DPMatrix_<int, TDPMatrixSpec> TDPMatrix;
-    typedef typename Value<TDPMatrix>::Type TDPCell;
-
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
-    TDPMatrix dpMatrix;
-    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
-    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 3);
-
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellHorizontal, TDPCell());
-
-    dpScoreMatrixNavigator._prevCellHorizontal = 20;
-    SEQAN_ASSERT_EQ(previousCellHorizontal(dpScoreMatrixNavigator), 20);
-
-    const DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigatorConst(dpScoreMatrixNavigator);
-    SEQAN_ASSERT_EQ(previousCellHorizontal(dpScoreMatrixNavigatorConst), 20);
+    const DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigatorConst(dpScoreMatrixNavigator);
+    SEQAN_ASSERT_EQ(_scoreOfCell(value(dpScoreMatrixNavigatorConst)), 20);
 }
 
 template <typename TDPMatrixSpec>
-void testAlignmentDPScoreMatrixNavigatorPreviousCellVertical(TDPMatrixSpec const)
+void testAlignmentDPScoreMatrixNavigatorPreviousCellHorizontal(TDPMatrixSpec const)
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, TDPMatrixSpec> TDPMatrix;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, TDPMatrixSpec> TDPMatrix;
     typedef typename Value<TDPMatrix>::Type TDPCell;
 
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 3);
+    resize(dpMatrix, TDPCell{});
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-    SEQAN_ASSERT_EQ(dpScoreMatrixNavigator._prevCellVertical, TDPCell());
+    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
-    dpScoreMatrixNavigator._prevCellVertical = 20;
-    SEQAN_ASSERT_EQ(previousCellVertical(dpScoreMatrixNavigator), 20);
+    // A hacky way to test the previous cell function.
+    dpScoreMatrixNavigator._prevColIterator = dpScoreMatrixNavigator._activeColIterator;
+    *dpScoreMatrixNavigator._activeColIterator = 20;
+    SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(dpScoreMatrixNavigator)), 20);
 
-    const DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigatorConst(dpScoreMatrixNavigator);
-    SEQAN_ASSERT_EQ(previousCellVertical(dpScoreMatrixNavigatorConst), 20);
+    const DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigatorConst(dpScoreMatrixNavigator);
+    SEQAN_ASSERT_EQ(_scoreOfCell(previousCellHorizontal(dpScoreMatrixNavigatorConst)), 20);
 }
 
 template <typename TDPMatrixSpec>
@@ -1278,16 +433,16 @@ void testAlignmentDPScoreMatrixNavigatorCoordinate(TDPMatrixSpec const)
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, TDPMatrixSpec> TDPMatrix;
-
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, TDPMatrixSpec> TDPMatrix;
+    typedef typename Value<TDPMatrix>::Type TDPCell;
 
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 3);
+    resize(dpMatrix, TDPCell{});
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
     dpScoreMatrixNavigator._activeColIterator += 7;
     dpScoreMatrixNavigator._prevColIterator += 7;
@@ -1301,20 +456,21 @@ void testAlignmentDPScoreMatrixNavigatorContainer(TDPMatrixSpec const)
 {
     using namespace seqan;
 
-    typedef DPMatrix_<int, TDPMatrixSpec> TDPMatrix;
-
-    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigator;
+    typedef DPMatrix_<DPCell_<int, LinearGaps>, TDPMatrixSpec> TDPMatrix;
+    typedef typename Value<TDPMatrix>::Type TDPCell;
 
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
-    resize(dpMatrix, 3);
+    resize(dpMatrix, TDPCell{});
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
     SEQAN_ASSERT_EQ(&container(dpScoreMatrixNavigator), &dpMatrix);
 
-    const DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise> dpScoreMatrixNavigatorConst(dpScoreMatrixNavigator);
+    const DPMatrixNavigator_<TDPMatrix, DPScoreMatrix, NavigateColumnWise>
+        dpScoreMatrixNavigatorConst(dpScoreMatrixNavigator);
     SEQAN_ASSERT_EQ(&container(dpScoreMatrixNavigatorConst), &dpMatrix);
 }
 
@@ -1323,15 +479,6 @@ void testAlignmentDPScoreMatrixNavigatorContainer(TDPMatrixSpec const)
 // Test constructor                                  [DPScoreMatrix, FullDPMatrix]
 // ----------------------------------------------------------------------------
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_constructor)
-{
-    testAlignmentDPMatrixScoreNavigatorConstructorDefault(seqan::FullDPMatrix());
-}
-
-// ----------------------------------------------------------------------------
-// Test functions                                  [DPScoreMatrix, FullDPMatrix]
-// ----------------------------------------------------------------------------
-
 SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_init_unbanded)
 {
     testAlignmentDPMatrixNavigatorScoreMarixInitUnbanded();
@@ -1342,34 +489,28 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_init_band
     testAlignmentDPMatrixNavigatorScoreMarixInitBanded();
 }
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_go_next_cell)
-{
-    testAlignmentDPMatrixNavigatorScoreMarixGoNextCell();
-}
-
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_assign_value)
-{
-    testAlignmentDPScoreMatrixNavigatorAssignValue(seqan::FullDPMatrix());
-}
+// ----------------------------------------------------------------------------
+// Test functions                                  [DPScoreMatrix, FullDPMatrix]
+// ----------------------------------------------------------------------------
 
 SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_value)
 {
     testAlignmentDPScoreMatrixNavigatorValue(seqan::FullDPMatrix());
 }
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_previous_cell_diagonal)
+SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_previous_cell_horizontal)
 {
-    testAlignmentDPScoreMatrixNavigatorPreviousCellDiagonal(seqan::FullDPMatrix());
+    testAlignmentDPScoreMatrixNavigatorPreviousCellHorizontal(seqan::FullDPMatrix());
 }
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_previous_cell_horizontal)
+SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_go_next_cell)
 {
-    testAlignmentDPScoreMatrixNavigatorPreviousCellHorizontal(seqan::FullDPMatrix());
+    testAlignmentDPMatrixNavigatorScoreMarixGoNextCell();
 }
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_previous_cell_vertical)
+SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_assign_value)
 {
-    testAlignmentDPScoreMatrixNavigatorPreviousCellVertical(seqan::FullDPMatrix());
+    testAlignmentDPScoreMatrixNavigatorAssignValue(seqan::FullDPMatrix());
 }
 
 SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_coordinate)
@@ -1386,15 +527,6 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_full_container
 // Test constructor                                [DPScoreMatrix, SparseDPMatrix]
 // ----------------------------------------------------------------------------
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_constructor)
-{
-    testAlignmentDPMatrixScoreNavigatorConstructorDefault(seqan::SparseDPMatrix());
-}
-
-// ----------------------------------------------------------------------------
-// Test functions                                [DPScoreMatrix, SparseDPMatrix]
-// ----------------------------------------------------------------------------
-
 SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_init_unbanded)
 {
     testAlignmentDPMatrixNavigatorScoreMarixSparseInitUnbanded();
@@ -1405,34 +537,28 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_init_ba
     testAlignmentDPMatrixNavigatorScoreMarixSparseInitBanded();
 }
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_go_next)
-{
-    testAlignmentDPMatrixNavigatorScoreMarixSparseGoNext();
-}
-
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_assign_value)
-{
-    testAlignmentDPScoreMatrixNavigatorAssignValue(seqan::SparseDPMatrix());
-}
+// ----------------------------------------------------------------------------
+// Test functions                                [DPScoreMatrix, SparseDPMatrix]
+// ----------------------------------------------------------------------------
 
 SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_value)
 {
     testAlignmentDPScoreMatrixNavigatorValue(seqan::SparseDPMatrix());
 }
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_previous_cell_diagonal)
+SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_previous_cell_horizontal)
 {
-    testAlignmentDPScoreMatrixNavigatorPreviousCellDiagonal(seqan::SparseDPMatrix());
+    testAlignmentDPScoreMatrixNavigatorPreviousCellHorizontal(seqan::SparseDPMatrix());
 }
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_previous_cell_horizontal)
+SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_go_next)
 {
-    testAlignmentDPScoreMatrixNavigatorPreviousCellHorizontal(seqan::SparseDPMatrix());
+    testAlignmentDPMatrixNavigatorScoreMarixSparseGoNextCell();
 }
 
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_previous_cell_vertical)
+SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_assign_value)
 {
-    testAlignmentDPScoreMatrixNavigatorPreviousCellVertical(seqan::SparseDPMatrix());
+    testAlignmentDPScoreMatrixNavigatorAssignValue(seqan::SparseDPMatrix());
 }
 
 SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_coordinate)
@@ -1446,16 +572,6 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_score_matrix_sparse_contain
 }
 
 // ----------------------------------------------------------------------------
-// Test constructor                                  [DPTraceMatrix, FullDPMatrix]
-// ----------------------------------------------------------------------------
-
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_constructor)
-{
-    testAlignmentDPMatrixTraceNavigatorConstructorDefault(seqan::TracebackOn<seqan::GapsLeft>());
-    testAlignmentDPMatrixTraceNavigatorConstructorDefault(seqan::TracebackOff());
-}
-
-// ----------------------------------------------------------------------------
 // Test functions                                  [DPTraceMatrix, FullDPMatrix]
 // ----------------------------------------------------------------------------
 
@@ -1465,14 +581,13 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_init_u
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> dpTraceMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
     resize(dpMatrix);
 
-    _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise>
+        dpTraceMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
     SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._ptrDataContainer, &dpMatrix);
     SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
@@ -1485,14 +600,13 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_disabled_init_
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOff>, NavigateColumnWise> dpTraceMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
     resize(dpMatrix);
 
-    _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOff>, NavigateColumnWise>
+        dpTraceMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
     SEQAN_ASSERT_NEQ(dpTraceMatrixNavigator._ptrDataContainer, &dpMatrix);
     SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 0);
@@ -1504,15 +618,14 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_init_b
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> dpTraceMatrixNavigator;
-
     { // Case1: Band intersects with poit of origin.
         TDPMatrix dpMatrix;
         setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
         setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 8);
         resize(dpMatrix);
 
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOn>(-4, 3));
+        DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWiseBanded>
+            dpTraceMatrixNavigator{dpMatrix, DPBandConfig<BandOn>{-4, 3}};
 
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._ptrDataContainer, &dpMatrix);
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
@@ -1526,7 +639,8 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_init_b
         resize(dpMatrix2);
 
         value(host(dpMatrix2), 0) = 10;
-        _init(dpTraceMatrixNavigator, dpMatrix2, DPBandConfig<BandOn>(0, 7));
+        DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWiseBanded>
+            dpTraceMatrixNavigator{dpMatrix2, DPBandConfig<BandOn>{0, 7}};
 
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._ptrDataContainer, &dpMatrix2);
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix2, Standard()), 7);
@@ -1540,7 +654,8 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_init_b
         resize(dpMatrix3);
 
 
-        _init(dpTraceMatrixNavigator, dpMatrix3, DPBandConfig<BandOn>(-7, 0));
+        DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWiseBanded>
+            dpTraceMatrixNavigator{dpMatrix3, DPBandConfig<BandOn>{-7, 0}};
 
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._ptrDataContainer, &dpMatrix3);
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix3, Standard()), 0);
@@ -1554,15 +669,14 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_disabled_init_
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOff>, NavigateColumnWise> dpTraceMatrixNavigator;
-
     { // Case1: Band intersects with poit of origin.
         TDPMatrix dpMatrix;
         setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
         setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 8);
         resize(dpMatrix);
 
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOn>(-4, 3));
+        DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOff>, NavigateColumnWiseBanded>
+            dpTraceMatrixNavigator{dpMatrix, DPBandConfig<BandOn>{-4, 3}};
 
         SEQAN_ASSERT_NEQ(dpTraceMatrixNavigator._ptrDataContainer, &dpMatrix);
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 0);
@@ -1575,7 +689,8 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_disabled_init_
         resize(dpMatrix2);
 
         value(host(dpMatrix2), 0) = 10;
-        _init(dpTraceMatrixNavigator, dpMatrix2, DPBandConfig<BandOn>(0, 7));
+        DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOff>, NavigateColumnWiseBanded>
+            dpTraceMatrixNavigator{dpMatrix2, DPBandConfig<BandOn>{0, 7}};
 
         SEQAN_ASSERT_NEQ(dpTraceMatrixNavigator._ptrDataContainer, &dpMatrix2);
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 0);
@@ -1588,7 +703,8 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_disabled_init_
         resize(dpMatrix3);
 
 
-        _init(dpTraceMatrixNavigator, dpMatrix3, DPBandConfig<BandOn>(-7, 0));
+        DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOff>, NavigateColumnWiseBanded>
+            dpTraceMatrixNavigator{dpMatrix3, DPBandConfig<BandOn>{-7, 0}};
 
         SEQAN_ASSERT_NEQ(dpTraceMatrixNavigator._ptrDataContainer, &dpMatrix3);
         SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 0);
@@ -1601,345 +717,51 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_go_nex
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> dpTraceMatrixNavigator;
-
-    TDPMatrix dpMatrix;
-    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
-    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 3);
-    resize(dpMatrix, 0);
-    host(dpMatrix)[0] = 0;
-    host(dpMatrix)[1] = 1;
-    host(dpMatrix)[2] = 2;
-    host(dpMatrix)[3] = 3;
-    host(dpMatrix)[4] = 4;
-    host(dpMatrix)[5] = 5;
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 0);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 1);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 2);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-        ++dpTraceMatrixNavigator._laneLeap;  // For the test we simulate as if we were in a band.
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 2);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-        ++dpTraceMatrixNavigator._laneLeap;
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 2);
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), FirstCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 3);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), InnerCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 4);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-
-        _goNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), LastCell());
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._activeColIterator - begin(dpMatrix, Standard()), 5);
-        SEQAN_ASSERT_EQ(dpTraceMatrixNavigator._laneLeap, 1);
-    }
-}
-
-template <typename TNavigator, typename TMetaDescriptor, typename TCell>
-void _testGoNextCell(TNavigator & navi, TMetaDescriptor const &, TCell const &)
-{
-    using namespace seqan;
-
-    _goNextCell(navi, TMetaDescriptor(), TCell());
-    SEQAN_ASSERT_EQ(navi._laneLeap, 0);
-}
-
-SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_disabled_go_next)
-{
-    using namespace seqan;
-
-    typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
-
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOff>, NavigateColumnWise> dpTraceMatrixNavigator;
-
     TDPMatrix dpMatrix;
-    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
-    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 3);
-    resize(dpMatrix, 0);
-    host(dpMatrix)[0] = 0;
-    host(dpMatrix)[1] = 1;
-    host(dpMatrix)[2] = 2;
-    host(dpMatrix)[3] = 3;
-    host(dpMatrix)[4] = 4;
-    host(dpMatrix)[5] = 5;
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnTop>(), LastCell());
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnMiddle>(), LastCell());
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, PartialColumnBottom>(), LastCell());
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInitialColumn, FullColumn>(), LastCell());
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        dpTraceMatrixNavigator._activeColIterator += 2;
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnTop>(), LastCell());
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnMiddle>(), LastCell());
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, PartialColumnBottom>(), LastCell());
-    }
-
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPInnerColumn, FullColumn>(), LastCell());
-    }
+    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 4);
+    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 4);
+    resize(dpMatrix);
 
-    {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    std::iota(begin(host(dpMatrix), Standard()), end(host(dpMatrix), Standard()), 0);
 
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnTop>(), LastCell());
-    }
+    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise>
+        navi{dpMatrix, DPBandConfig<BandOff>()};
 
+    // Move along initial column.
+    _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, FirstCell{});
+    SEQAN_ASSERT_EQ(value(navi), 0);
+    for (int v_pos = 1; v_pos < 3; ++v_pos)
     {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnMiddle>(), LastCell());
+        _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, InnerCell{});
+        SEQAN_ASSERT_EQ(value(navi), v_pos);
     }
+    _goNextCell(navi, MetaColumnDescriptor<DPInitialColumn, FullColumn>{}, LastCell{});
+    SEQAN_ASSERT_EQ(value(navi), 3);
 
+    // Move along inner columns.
+    for (int h_pos = 1; h_pos < 3; ++h_pos)
     {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, PartialColumnBottom>(), LastCell());
+        _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, FirstCell{});
+        SEQAN_ASSERT_EQ(value(navi), h_pos * 4);
+        for (int v_pos = 1; v_pos < 3; ++v_pos)
+        {
+            _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, InnerCell{});
+            SEQAN_ASSERT_EQ(value(navi), h_pos * 4 + v_pos);
+        }
+        _goNextCell(navi, MetaColumnDescriptor<DPInnerColumn, FullColumn>{}, LastCell{});
+        SEQAN_ASSERT_EQ(value(navi), h_pos * 4 + 3);
     }
 
+    // Move along last column.
+    _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, FirstCell{});
+    SEQAN_ASSERT_EQ(value(navi), 12);
+    for (int v_pos = 1; v_pos < 3; ++v_pos)
     {
-        _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), FirstCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), InnerCell());
-        _testGoNextCell(dpTraceMatrixNavigator, MetaColumnDescriptor<DPFinalColumn, FullColumn>(), LastCell());
+        _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, InnerCell{});
+        SEQAN_ASSERT_EQ(value(navi), 12 + v_pos);
     }
+    _goNextCell(navi, MetaColumnDescriptor<DPFinalColumn, FullColumn>{}, LastCell{});
+    SEQAN_ASSERT_EQ(value(navi), 15);
 }
 
 SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_assign_value)
@@ -1948,17 +770,16 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_assign
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> dpScoreMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
     resize(dpMatrix, 3);
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise>
+        dpTraceMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
-    assignValue(dpScoreMatrixNavigator, 20);
-    SEQAN_ASSERT_EQ(value(dpScoreMatrixNavigator._activeColIterator), 20);
+    assignValue(dpTraceMatrixNavigator, 20);
+    SEQAN_ASSERT_EQ(value(dpTraceMatrixNavigator._activeColIterator), 20);
 }
 
 
@@ -1968,19 +789,18 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_value)
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> dpTraceMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
     resize(dpMatrix, 3);
 
-    _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise>
+        dpTraceMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
     assignValue(dpTraceMatrixNavigator, 20);
     SEQAN_ASSERT_EQ(value(dpTraceMatrixNavigator), 20);
-
-    const DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> dpTraceMatrixNavigatorConst(dpTraceMatrixNavigator);
+    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> const
+        dpTraceMatrixNavigatorConst(dpTraceMatrixNavigator);
     SEQAN_ASSERT_EQ(value(dpTraceMatrixNavigatorConst), 20);
 }
 
@@ -1991,19 +811,18 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_coordi
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> dpScoreMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
     resize(dpMatrix, 3);
 
-    _init(dpScoreMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise>
+        dpTraceMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
-    dpScoreMatrixNavigator._activeColIterator += 7;
+    dpTraceMatrixNavigator._activeColIterator += 7;
 
-    SEQAN_ASSERT_EQ(coordinate(dpScoreMatrixNavigator, +DPMatrixDimension_::HORIZONTAL), 0u);
-    SEQAN_ASSERT_EQ(coordinate(dpScoreMatrixNavigator, +DPMatrixDimension_::VERTICAL), 7u);
+    SEQAN_ASSERT_EQ(coordinate(dpTraceMatrixNavigator, +DPMatrixDimension_::HORIZONTAL), 0u);
+    SEQAN_ASSERT_EQ(coordinate(dpTraceMatrixNavigator, +DPMatrixDimension_::VERTICAL), 7u);
 }
 
 SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_container)
@@ -2012,14 +831,13 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_contai
 
     typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
 
-    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> dpTraceMatrixNavigator;
-
     TDPMatrix dpMatrix;
     setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
     setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
     resize(dpMatrix, 3);
 
-    _init(dpTraceMatrixNavigator, dpMatrix, DPBandConfig<BandOff>());
+    DPMatrixNavigator_<TDPMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise>
+        dpTraceMatrixNavigator{dpMatrix, DPBandConfig<BandOff>{}};
 
     SEQAN_ASSERT_EQ(&container(dpTraceMatrixNavigator), &dpMatrix);
 
@@ -2027,4 +845,30 @@ SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_contai
     SEQAN_ASSERT_EQ(&container(dpTraceMatrixNavigatorConst), &dpMatrix);
 }
 
+SEQAN_DEFINE_TEST(test_alignment_dp_matrix_navigator_trace_matrix_enabled_to_global_position)
+{
+    using namespace seqan;
+
+    typedef DPMatrix_<int, FullDPMatrix> TDPMatrix;
+
+    TDPMatrix dpMatrix;
+    setLength(dpMatrix, DPMatrixDimension_::HORIZONTAL, 10);
+    setLength(dpMatrix, DPMatrixDimension_::VERTICAL, 10);
+    resize(dpMatrix);
+
+    DPMatrixNavigator_<TDPMatrix,
+                       DPTraceMatrix<TracebackOn<> >,
+                       NavigateColumnWise> navi{dpMatrix, DPBandConfig<BandOff>{}};
+
+    for (unsigned i = 0; i < length(dpMatrix, +DPMatrixDimension_::HORIZONTAL); ++i)
+    {
+        for (unsigned j = 0; j < length(dpMatrix, +DPMatrixDimension_::VERTICAL); ++j)
+        {
+            _setToPosition(navi, toGlobalPosition(navi, i, j));
+            SEQAN_ASSERT_EQ(i, coordinate(navi, +DPMatrixDimension_::HORIZONTAL));
+            SEQAN_ASSERT_EQ(j, coordinate(navi, +DPMatrixDimension_::VERTICAL));
+        }
+    }
+}
+
 #endif  // #ifndef SANDBOX_RMAERKER_TESTS_ALIGN2_TEST_ALIGNMENT_DP_MATRIX_NAVIGATOR_H_
diff --git a/tests/align/test_alignment_dp_trace_segment.h b/tests/align/test_alignment_dp_trace_segment.h
index b15bf46..cde038f 100644
--- a/tests/align/test_alignment_dp_trace_segment.h
+++ b/tests/align/test_alignment_dp_trace_segment.h
@@ -53,7 +53,7 @@ testAlignmentTracebackTraceSegmentsConstructor()
         SEQAN_ASSERT_EQ(traceSegment._horizontalBeginPos, (TPosition) 0);
         SEQAN_ASSERT_EQ(traceSegment._verticalBeginPos, (TPosition) 0);
         SEQAN_ASSERT_EQ(traceSegment._length, (TSize) 0);
-        SEQAN_ASSERT_EQ(traceSegment._traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(traceSegment._traceValue, TraceBitMap_<>::NONE);
     }
 
     { // test copy ctor
@@ -61,30 +61,30 @@ testAlignmentTracebackTraceSegmentsConstructor()
         traceSegment._horizontalBeginPos = 10;
         traceSegment._verticalBeginPos = 3;
         traceSegment._length = 5;
-        traceSegment._traceValue = +TraceBitMap_<>::DIAGONAL;
+        traceSegment._traceValue = TraceBitMap_<>::DIAGONAL;
 
         TTraceSegment traceSegment2(traceSegment);
 
         SEQAN_ASSERT_EQ(traceSegment2._horizontalBeginPos, (TPosition) 10);
         SEQAN_ASSERT_EQ(traceSegment2._verticalBeginPos, (TPosition) 3);
         SEQAN_ASSERT_EQ(traceSegment2._length, (TSize) 5);
-        SEQAN_ASSERT_EQ(traceSegment2._traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(traceSegment2._traceValue, TraceBitMap_<>::DIAGONAL);
 
         TTraceSegment traceSegment3 = traceSegment;
 
         SEQAN_ASSERT_EQ(traceSegment3._horizontalBeginPos, (TPosition) 10);
         SEQAN_ASSERT_EQ(traceSegment3._verticalBeginPos, (TPosition) 3);
         SEQAN_ASSERT_EQ(traceSegment3._length, (TSize) 5);
-        SEQAN_ASSERT_EQ(traceSegment3._traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(traceSegment3._traceValue, TraceBitMap_<>::DIAGONAL);
     }
 
     { // test additional ctor
-        TTraceSegment traceSegment(12, 13, 8, +TraceBitMap_<>::VERTICAL);
+        TTraceSegment traceSegment(12, 13, 8, TraceBitMap_<>::VERTICAL);
 
         SEQAN_ASSERT_EQ(traceSegment._horizontalBeginPos, (TPosition) 12);
         SEQAN_ASSERT_EQ(traceSegment._verticalBeginPos, (TPosition) 13);
         SEQAN_ASSERT_EQ(traceSegment._length, (TSize) 8);
-        SEQAN_ASSERT_EQ(traceSegment._traceValue, +TraceBitMap_<>::VERTICAL);
+        SEQAN_ASSERT_EQ(traceSegment._traceValue, TraceBitMap_<>::VERTICAL);
     }
 }
 
@@ -101,21 +101,21 @@ testAlignmentTracebackTraceSegmentsAssignment()
         traceSegment._horizontalBeginPos = 10;
         traceSegment._verticalBeginPos = 3;
         traceSegment._length = 5;
-        traceSegment._traceValue = +TraceBitMap_<>::DIAGONAL;
+        traceSegment._traceValue = TraceBitMap_<>::DIAGONAL;
 
         TTraceSegment traceSegment2;
 
         SEQAN_ASSERT_EQ(traceSegment2._horizontalBeginPos, (TPosition) 0);
         SEQAN_ASSERT_EQ(traceSegment2._verticalBeginPos, (TPosition) 0);
         SEQAN_ASSERT_EQ(traceSegment2._length, (TSize) 0);
-        SEQAN_ASSERT_EQ(traceSegment2._traceValue, +TraceBitMap_<>::NONE);
+        SEQAN_ASSERT_EQ(traceSegment2._traceValue, TraceBitMap_<>::NONE);
 
         traceSegment2 = traceSegment;
 
         SEQAN_ASSERT_EQ(traceSegment2._horizontalBeginPos, (TPosition) 10);
         SEQAN_ASSERT_EQ(traceSegment2._verticalBeginPos, (TPosition) 3);
         SEQAN_ASSERT_EQ(traceSegment2._length, (TSize) 5);
-        SEQAN_ASSERT_EQ(traceSegment2._traceValue, +TraceBitMap_<>::DIAGONAL);
+        SEQAN_ASSERT_EQ(traceSegment2._traceValue, TraceBitMap_<>::DIAGONAL);
     }
 }
 
@@ -131,12 +131,12 @@ testAlignmentTracebackTraceSegmentsCompare()
     traceSegment._horizontalBeginPos = 10;
     traceSegment._verticalBeginPos = 3;
     traceSegment._length = 5;
-    traceSegment._traceValue = +TraceBitMap_<>::DIAGONAL;
+    traceSegment._traceValue = TraceBitMap_<>::DIAGONAL;
 
     TTraceSegment traceSegment2(traceSegment);
 
     SEQAN_ASSERT(traceSegment2 == traceSegment);
-    traceSegment._traceValue = +TraceBitMap_<>::HORIZONTAL;
+    traceSegment._traceValue = TraceBitMap_<>::HORIZONTAL;
     SEQAN_ASSERT(traceSegment2 !=  traceSegment);
 }
 
@@ -178,22 +178,22 @@ void testAlignmentTracebackRecordTrace(TTarget & target)
     _recordSegment(target, 0, 0, 3, tv1);
     _recordSegment(target, 0, 3, 5, tv2);
     _recordSegment(target, 5, 8, 3, tv3);
-    _recordSegment(target, 8, 8, 0, +TraceBitMap_<>::DIAGONAL);
+    _recordSegment(target, 8, 8, 0, TraceBitMap_<>::DIAGONAL);
 
 
 
     SEQAN_ASSERT_EQ(target[0]._horizontalBeginPos, 0);
     SEQAN_ASSERT_EQ(target[0]._verticalBeginPos, 0);
     SEQAN_ASSERT_EQ(target[0]._length, 3);
-    SEQAN_ASSERT_EQ(target[0]._traceValue, +TraceBitMap_<>::DIAGONAL);
+    SEQAN_ASSERT_EQ(target[0]._traceValue, TraceBitMap_<>::DIAGONAL);
     SEQAN_ASSERT_EQ(target[1]._horizontalBeginPos, 0);
     SEQAN_ASSERT_EQ(target[1]._verticalBeginPos, 3);
     SEQAN_ASSERT_EQ(target[1]._length, 5);
-    SEQAN_ASSERT_EQ(target[1]._traceValue, +TraceBitMap_<>::VERTICAL);
+    SEQAN_ASSERT_EQ(target[1]._traceValue, TraceBitMap_<>::VERTICAL);
     SEQAN_ASSERT_EQ(target[2]._horizontalBeginPos, 5);
     SEQAN_ASSERT_EQ(target[2]._verticalBeginPos, 8);
     SEQAN_ASSERT_EQ(target[2]._length, 3);
-    SEQAN_ASSERT_EQ(target[2]._traceValue, +TraceBitMap_<>::HORIZONTAL);
+    SEQAN_ASSERT_EQ(target[2]._traceValue, TraceBitMap_<>::HORIZONTAL);
 
     SEQAN_ASSERT_EQ(length(target), 3u);
 }
@@ -245,11 +245,11 @@ void testAlignmentTracebackTraceSegmentGetEndHorizontal()
     traceSegm._horizontalBeginPos = 5;
     traceSegm._verticalBeginPos = 12;
     traceSegm._length = 7;
-    traceSegm._traceValue = +TraceBitMap_<>::HORIZONTAL;
+    traceSegm._traceValue = TraceBitMap_<>::HORIZONTAL;
 
     SEQAN_ASSERT_EQ(_getEndHorizontal(traceSegm), 12);
 
-    traceSegm._traceValue = +TraceBitMap_<>::VERTICAL;
+    traceSegm._traceValue = TraceBitMap_<>::VERTICAL;
     SEQAN_ASSERT_EQ(_getEndHorizontal(traceSegm), 5);
 }
 
@@ -264,11 +264,11 @@ void testAlignmentTracebackTraceSegmentGetEndVertical()
     traceSegm._horizontalBeginPos = 5;
     traceSegm._verticalBeginPos = 12;
     traceSegm._length = 7;
-    traceSegm._traceValue = +TraceBitMap_<>::VERTICAL;
+    traceSegm._traceValue = TraceBitMap_<>::VERTICAL;
 
     SEQAN_ASSERT_EQ(_getEndVertical(traceSegm), 19);
 
-    traceSegm._traceValue = +TraceBitMap_<>::HORIZONTAL;
+    traceSegm._traceValue = TraceBitMap_<>::HORIZONTAL;
     SEQAN_ASSERT_EQ(_getEndVertical(traceSegm), 12);
 }
 
@@ -276,12 +276,12 @@ void testAlignmentTracebackTraceSegmentTranslateTraceValue()
 {
     using namespace seqan;
 
-    SEQAN_ASSERT_EQ(_translateTraceValue(+TraceBitMap_<>::DIAGONAL), "D");
-    SEQAN_ASSERT_EQ(_translateTraceValue(+TraceBitMap_<>::VERTICAL), "V");
-    SEQAN_ASSERT_EQ(_translateTraceValue(+TraceBitMap_<>::HORIZONTAL), "H");
-    SEQAN_ASSERT_EQ(_translateTraceValue(+TraceBitMap_<>::VERTICAL_OPEN), "v");
-    SEQAN_ASSERT_EQ(_translateTraceValue(+TraceBitMap_<>::HORIZONTAL_OPEN), "h");
-    SEQAN_ASSERT_EQ(_translateTraceValue(+TraceBitMap_<>::NONE), "0");
+    SEQAN_ASSERT_EQ(_translateTraceValue(TraceBitMap_<>::DIAGONAL), "D");
+    SEQAN_ASSERT_EQ(_translateTraceValue(TraceBitMap_<>::VERTICAL), "V");
+    SEQAN_ASSERT_EQ(_translateTraceValue(TraceBitMap_<>::HORIZONTAL), "H");
+    SEQAN_ASSERT_EQ(_translateTraceValue(TraceBitMap_<>::VERTICAL_OPEN), "v");
+    SEQAN_ASSERT_EQ(_translateTraceValue(TraceBitMap_<>::HORIZONTAL_OPEN), "h");
+    SEQAN_ASSERT_EQ(_translateTraceValue(TraceBitMap_<>::NONE), "0");
 }
 
 void testAlignmentTracebackTraceSegmentStreamOperator()
@@ -295,7 +295,7 @@ void testAlignmentTracebackTraceSegmentStreamOperator()
     traceSegm._horizontalBeginPos = 5;
     traceSegm._verticalBeginPos = 12;
     traceSegm._length = 7;
-    traceSegm._traceValue = +TraceBitMap_<>::DIAGONAL;
+    traceSegm._traceValue = TraceBitMap_<>::DIAGONAL;
 
     std::stringstream ss;
     ss << traceSegm;
diff --git a/tests/align/test_alignment_dp_traceback.h b/tests/align/test_alignment_dp_traceback.h
index c396043..ddfc78f 100644
--- a/tests/align/test_alignment_dp_traceback.h
+++ b/tests/align/test_alignment_dp_traceback.h
@@ -57,28 +57,27 @@ SEQAN_DEFINE_TEST(test_align2_traceback_affine)
 
     resize(traceMatrix);
 
-    value(traceMatrix, 0, 0) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 0) = +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 2, 0) = +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 3, 0) = +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 0, 0) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 0) = TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 2, 0) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 3, 0) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
 
-    value(traceMatrix, 0, 1) = +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 1, 1) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 2, 1) = +TraceBitMap_<>::HORIZONTAL_OPEN | +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | +TraceBitMap_<>::VERTICAL_OPEN;
-    value(traceMatrix, 3, 1) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 0, 1) = TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 1, 1) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 2, 1) = TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::VERTICAL_OPEN;
+    value(traceMatrix, 3, 1) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
 
-    value(traceMatrix, 0, 2) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 1, 2) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 2, 2) = +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 3, 2) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 0, 2) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 1, 2) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 2, 2) = TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 3, 2) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
 
-    value(traceMatrix, 0, 3) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 1, 3) = +TraceBitMap_<>::HORIZONTAL_OPEN | +TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 2, 3) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 3, 3) = +TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 0, 3) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 1, 3) = TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 2, 3) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 3, 3) = TraceBitMap_<>::DIAGONAL;
 
-    TDPTraceNavigator navigator;
-    _init(navigator, traceMatrix, DPBandConfig<BandOff>());
+    TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOff>()};
 
     DnaString str0 = "ACG";
     DnaString str1 = "ACG";
@@ -87,55 +86,55 @@ SEQAN_DEFINE_TEST(test_align2_traceback_affine)
     dpScout._maxHostPosition = 15;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
     SEQAN_ASSERT_EQ(length(target), 1u);
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(0, 0, 3, +TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(0, 0, 3, TraceBitMap_<>::DIAGONAL));
 
     clear(target);
     dpScout._maxHostPosition = 14;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
     SEQAN_ASSERT_EQ(length(target), 3u);
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 2, 1, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 2, 3, +TraceBitMap_<>::HORIZONTAL));
-    SEQAN_ASSERT_EQ(target[2], TTraceSegment(0, 0, 2, +TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 2, 1, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 2, 3, TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[2], TTraceSegment(0, 0, 2, TraceBitMap_<>::VERTICAL));
 
     clear(target);
     dpScout._maxHostPosition = 13;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
     SEQAN_ASSERT_EQ(length(target), 4u);
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 1, 2, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(2, 1, 1, +TraceBitMap_<>::HORIZONTAL));
-    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 0, 1, +TraceBitMap_<>::DIAGONAL));
-    SEQAN_ASSERT_EQ(target[3], TTraceSegment(0, 0, 1, +TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 1, 2, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(2, 1, 1, TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 0, 1, TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[3], TTraceSegment(0, 0, 1, TraceBitMap_<>::HORIZONTAL));
 
     clear(target);
     dpScout._maxHostPosition = 12;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
     SEQAN_ASSERT_EQ(length(target), 2u);
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 0, 3, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 3, +TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 0, 3, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 3, TraceBitMap_<>::HORIZONTAL));
 
     clear(target);
     dpScout._maxHostPosition = 11;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
     SEQAN_ASSERT_EQ(length(target), 4u);
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 3, 1, +TraceBitMap_<>::HORIZONTAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(2, 1, 2, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 0, 1, +TraceBitMap_<>::DIAGONAL));
-    SEQAN_ASSERT_EQ(target[3], TTraceSegment(0, 0, 1, +TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 3, 1, TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(2, 1, 2, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 0, 1, TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[3], TTraceSegment(0, 0, 1, TraceBitMap_<>::HORIZONTAL));
 
     clear(target);
     dpScout._maxHostPosition = 7;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
     SEQAN_ASSERT_EQ(length(target), 3u);
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(1, 3, 2, +TraceBitMap_<>::HORIZONTAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(1, 1, 2, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[2], TTraceSegment(0, 0, 1, +TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(1, 3, 2, TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(1, 1, 2, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[2], TTraceSegment(0, 0, 1, TraceBitMap_<>::DIAGONAL));
 
     clear(target);
     dpScout._maxHostPosition = 3;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
     SEQAN_ASSERT_EQ(length(target), 2u);
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(0, 3, 3, +TraceBitMap_<>::HORIZONTAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 3, +TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(0, 3, 3, TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 3, TraceBitMap_<>::VERTICAL));
 }
 
 SEQAN_DEFINE_TEST(test_align2_traceback_linear_unbanded_alignment)
@@ -157,28 +156,27 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_unbanded_alignment)
 
     resize(traceMatrix);
 
-    value(traceMatrix, 0, 0) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 0) = +TraceBitMap_<>::VERTICAL;
-    value(traceMatrix, 2, 0) = +TraceBitMap_<>::VERTICAL;
-    value(traceMatrix, 3, 0) = +TraceBitMap_<>::VERTICAL;
+    value(traceMatrix, 0, 0) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 0) = TraceBitMap_<>::VERTICAL;
+    value(traceMatrix, 2, 0) = TraceBitMap_<>::VERTICAL;
+    value(traceMatrix, 3, 0) = TraceBitMap_<>::VERTICAL;
 
-    value(traceMatrix, 0, 1) = +TraceBitMap_<>::HORIZONTAL;
-    value(traceMatrix, 1, 1) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 2, 1) = +TraceBitMap_<>::HORIZONTAL | +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 3, 1) = +TraceBitMap_<>::NONE;
+    value(traceMatrix, 0, 1) = TraceBitMap_<>::HORIZONTAL;
+    value(traceMatrix, 1, 1) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 2, 1) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 3, 1) = TraceBitMap_<>::NONE;
 
-    value(traceMatrix, 0, 2) = +TraceBitMap_<>::HORIZONTAL;
-    value(traceMatrix, 1, 2) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 2, 2) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 3, 2) = +TraceBitMap_<>::NONE;
+    value(traceMatrix, 0, 2) = TraceBitMap_<>::HORIZONTAL;
+    value(traceMatrix, 1, 2) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 2, 2) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 3, 2) = TraceBitMap_<>::NONE;
 
-    value(traceMatrix, 0, 3) = +TraceBitMap_<>::HORIZONTAL;
-    value(traceMatrix, 1, 3) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 2, 3) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 3, 3) = +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL  | +TraceBitMap_<>::HORIZONTAL;
+    value(traceMatrix, 0, 3) = TraceBitMap_<>::HORIZONTAL;
+    value(traceMatrix, 1, 3) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 2, 3) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 3, 3) = TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL  | TraceBitMap_<>::HORIZONTAL;
 
-    TDPTraceNavigator navigator;
-    _init(navigator, traceMatrix, DPBandConfig<BandOff>());
+    TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOff>{}};
 
     DnaString str0 = "ACG";
     DnaString str1 = "ACG";
@@ -187,10 +185,10 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_unbanded_alignment)
     dpScout._maxHostPosition = 15;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 2, 1, +TraceBitMap_<>::DIAGONAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(1, 2, 1, +TraceBitMap_<>::HORIZONTAL));
-    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 1, 1, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[3], TTraceSegment(0, 0, 1, +TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 2, 1, TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(1, 2, 1, TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 1, 1, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[3], TTraceSegment(0, 0, 1, TraceBitMap_<>::DIAGONAL));
 }
 
 SEQAN_DEFINE_TEST(test_align2_traceback_linear_normal_banded_alignment)
@@ -202,7 +200,7 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_normal_banded_alignment)
     typedef typename TraceBitMap_<>::Type TTraceValue;
     typedef DPMatrix_<TTraceValue, FullDPMatrix> TTraceMatrix;
 
-    typedef DPMatrixNavigator_<TTraceMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> TDPTraceNavigator;
+    typedef DPMatrixNavigator_<TTraceMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWiseBanded> TDPTraceNavigator;
 
     String<TTraceSegment> target;
     TTraceMatrix traceMatrix;
@@ -212,29 +210,28 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_normal_banded_alignment)
 
     resize(traceMatrix);
 
-    value(traceMatrix, 0, 0) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 0) = +TraceBitMap_<>::VERTICAL;
-    value(traceMatrix, 2, 0) = +TraceBitMap_<>::VERTICAL;
+    value(traceMatrix, 0, 0) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 0) = TraceBitMap_<>::VERTICAL;
+    value(traceMatrix, 2, 0) = TraceBitMap_<>::VERTICAL;
 
-    value(traceMatrix, 0, 1) = +TraceBitMap_<>::HORIZONTAL;
-    value(traceMatrix, 1, 1) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 2, 1) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 0, 1) = TraceBitMap_<>::HORIZONTAL;
+    value(traceMatrix, 1, 1) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 2, 1) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
 
-    value(traceMatrix, 0, 2) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 2) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 2, 2) = +TraceBitMap_<>::NONE;
+    value(traceMatrix, 0, 2) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 2) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 2, 2) = TraceBitMap_<>::NONE;
 
-    value(traceMatrix, 0, 3) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 1, 3) = +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 2, 3) = +TraceBitMap_<>::NONE;
+    value(traceMatrix, 0, 3) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 1, 3) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 2, 3) = TraceBitMap_<>::NONE;
 
-    value(traceMatrix, 0, 4) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 4) = +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::VERTICAL  | +TraceBitMap_<>::HORIZONTAL;
-    value(traceMatrix, 2, 4) = +TraceBitMap_<>::NONE;
+    value(traceMatrix, 0, 4) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 4) = TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::VERTICAL  | TraceBitMap_<>::HORIZONTAL;
+    value(traceMatrix, 2, 4) = TraceBitMap_<>::NONE;
 
 
-    TDPTraceNavigator navigator;
-    _init(navigator, traceMatrix, DPBandConfig<BandOn>(-1, 1));
+    TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOn>{-1, 1}};
 
     DnaString str0 = "ACGT";
     DnaString str1 = "ACGT";
@@ -243,11 +240,11 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_normal_banded_alignment)
     dpScout._maxHostPosition = 13;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOn>(-1, 1), TDPProfile());
 
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 3, 1, +TraceBitMap_<>::DIAGONAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(3, 2, 1, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 2, 2, +TraceBitMap_<>::HORIZONTAL));
-    SEQAN_ASSERT_EQ(target[3], TTraceSegment(1, 1, 1, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[4], TTraceSegment(0, 0, 1, +TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 3, 1, TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(3, 2, 1, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 2, 2, TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[3], TTraceSegment(1, 1, 1, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[4], TTraceSegment(0, 0, 1, TraceBitMap_<>::DIAGONAL));
 }
 
 SEQAN_DEFINE_TEST(test_align2_traceback_linear_wide_banded_alignment)
@@ -259,7 +256,7 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_wide_banded_alignment)
     typedef typename TraceBitMap_<>::Type TTraceValue;
     typedef DPMatrix_<TTraceValue, FullDPMatrix> TTraceMatrix;
 
-    typedef DPMatrixNavigator_<TTraceMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> TDPTraceNavigator;
+    typedef DPMatrixNavigator_<TTraceMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWiseBanded> TDPTraceNavigator;
 
     String<TTraceSegment> target;
     TTraceMatrix traceMatrix;
@@ -269,64 +266,63 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_wide_banded_alignment)
 
     resize(traceMatrix);
 
-    value(traceMatrix, 0, 0) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 0) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 2, 0) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 3, 0) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 4, 0) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 5, 0) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 6, 0) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-
-    value(traceMatrix, 0, 1) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 1) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 2, 1) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 3, 1) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 4, 1) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 5, 1) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 6, 1) = +TraceBitMap_<>::NONE;
-
-    value(traceMatrix, 0, 2) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 1, 2) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 2, 2) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 3, 2) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 4, 2) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 5, 2) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 6, 2) = +TraceBitMap_<>::NONE;
-
-    value(traceMatrix, 0, 3) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 3) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 2, 3) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 3, 3) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 4, 3) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 5, 3) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 6, 3) = +TraceBitMap_<>::NONE;
-
-    value(traceMatrix, 0, 4) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 4) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 2, 4) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 3, 4) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 4, 4) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 5, 4) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 6, 4) = +TraceBitMap_<>::NONE;
-
-    value(traceMatrix, 0, 5) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 5) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 2, 5) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 3, 5) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 4, 5) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 5, 5) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 6, 5) = +TraceBitMap_<>::NONE;
-
-    value(traceMatrix, 0, 6) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 6) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 2, 6) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 3, 6) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 4, 6) = +TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 5, 6) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 6, 6) = +TraceBitMap_<>::NONE;
-
-    TDPTraceNavigator navigator;
-    _init(navigator, traceMatrix, DPBandConfig<BandOn>(-4, 4));
+    value(traceMatrix, 0, 0) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 0) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 2, 0) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 3, 0) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 4, 0) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 5, 0) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 6, 0) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+
+    value(traceMatrix, 0, 1) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 1) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 2, 1) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 3, 1) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 4, 1) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 5, 1) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 6, 1) = TraceBitMap_<>::NONE;
+
+    value(traceMatrix, 0, 2) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 1, 2) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 2, 2) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 3, 2) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 4, 2) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 5, 2) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 6, 2) = TraceBitMap_<>::NONE;
+
+    value(traceMatrix, 0, 3) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 3) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 2, 3) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 3, 3) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 4, 3) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 5, 3) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 6, 3) = TraceBitMap_<>::NONE;
+
+    value(traceMatrix, 0, 4) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 4) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 2, 4) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 3, 4) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 4, 4) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 5, 4) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 6, 4) = TraceBitMap_<>::NONE;
+
+    value(traceMatrix, 0, 5) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 5) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 2, 5) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 3, 5) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 4, 5) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 5, 5) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 6, 5) = TraceBitMap_<>::NONE;
+
+    value(traceMatrix, 0, 6) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 6) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 2, 6) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 3, 6) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 4, 6) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 5, 6) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 6, 6) = TraceBitMap_<>::NONE;
+
+    TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOn>{-4, 4}};
 
     DnaString str0 = "ACGTAC";
     DnaString str1 = "ACGTAC";
@@ -335,10 +331,10 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_wide_banded_alignment)
     dpScout._maxHostPosition = 46;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOn>(-4, 4), TDPProfile());
 
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(6, 3, 3, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(1, 3, 5, +TraceBitMap_<>::HORIZONTAL));
-    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 1, 2, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[3], TTraceSegment(0, 0, 1, +TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(6, 3, 3, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(1, 3, 5, TraceBitMap_<>::HORIZONTAL));
+    SEQAN_ASSERT_EQ(target[2], TTraceSegment(1, 1, 2, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[3], TTraceSegment(0, 0, 1, TraceBitMap_<>::DIAGONAL));
 }
 
 SEQAN_DEFINE_TEST(test_align2_traceback_linear_small_banded_alignment)
@@ -350,7 +346,7 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_small_banded_alignment)
     typedef typename TraceBitMap_<>::Type TTraceValue;
     typedef DPMatrix_<TTraceValue, FullDPMatrix> TTraceMatrix;
 
-    typedef DPMatrixNavigator_<TTraceMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWise> TDPTraceNavigator;
+    typedef DPMatrixNavigator_<TTraceMatrix, DPTraceMatrix<TracebackOn<> >, NavigateColumnWiseBanded> TDPTraceNavigator;
 
     String<TTraceSegment> target;
     TTraceMatrix traceMatrix;
@@ -360,16 +356,15 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_small_banded_alignment)
 
     resize(traceMatrix);
 
-    value(traceMatrix, 0, 0) = +TraceBitMap_<>::NONE;
+    value(traceMatrix, 0, 0) = TraceBitMap_<>::NONE;
 
-    value(traceMatrix, 0, 1) = +TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 0, 1) = TraceBitMap_<>::DIAGONAL;
 
-    value(traceMatrix, 0, 2) = +TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 0, 2) = TraceBitMap_<>::DIAGONAL;
 
-    value(traceMatrix, 0, 3) = +TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 0, 3) = TraceBitMap_<>::DIAGONAL;
 
-    TDPTraceNavigator navigator;
-    _init(navigator, traceMatrix, DPBandConfig<BandOn>(0, 0));
+    TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOn>{0, 0}};
 
     DnaString str0 = "ACG";
     DnaString str1 = "ACG";
@@ -378,7 +373,7 @@ SEQAN_DEFINE_TEST(test_align2_traceback_linear_small_banded_alignment)
     dpScout._maxHostPosition = 3;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOn>(0, 0), TDPProfile());
 
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(0, 0, 3, +TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(0, 0, 3, TraceBitMap_<>::DIAGONAL));
 }
 
 SEQAN_DEFINE_TEST(test_align2_traceback_gaps_left_linear_gaps)
@@ -400,24 +395,23 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_left_linear_gaps)
 
     resize(traceMatrix);
 
-    value(traceMatrix, 0, 0) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 0) = +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 2, 0) = +TraceBitMap_<>::VERTICAL;
-    value(traceMatrix, 3, 0) = +TraceBitMap_<>::VERTICAL;
+    value(traceMatrix, 0, 0) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 0) = TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 2, 0) = TraceBitMap_<>::VERTICAL;
+    value(traceMatrix, 3, 0) = TraceBitMap_<>::VERTICAL;
 
-    value(traceMatrix, 0, 1) = +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 1, 1) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 2, 1) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 3, 1) = +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::HORIZONTAL;
+    value(traceMatrix, 0, 1) = TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 1, 1) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 2, 1) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 3, 1) = TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::HORIZONTAL;
 
-    value(traceMatrix, 0, 2) = +TraceBitMap_<>::HORIZONTAL;
-    value(traceMatrix, 1, 2) = +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 2, 2) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 3, 2) = +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 0, 2) = TraceBitMap_<>::HORIZONTAL;
+    value(traceMatrix, 1, 2) = TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 2, 2) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 3, 2) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::DIAGONAL;
 
 
-    TDPTraceNavigator navigator;
-    _init(navigator, traceMatrix, DPBandConfig<BandOff>());
+    TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOff>()};
 
     DnaString str0 = "AC";
     DnaString str1 = "CCC";
@@ -426,8 +420,8 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_left_linear_gaps)
     dpScout._maxHostPosition = 11;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(0, 1, 2, +TraceBitMap_<>::DIAGONAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 1, +TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(0, 1, 2, TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 1, TraceBitMap_<>::VERTICAL));
 }
 
 SEQAN_DEFINE_TEST(test_align2_traceback_gaps_right_linear_gaps)
@@ -449,24 +443,23 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_right_linear_gaps)
 
     resize(traceMatrix);
 
-    value(traceMatrix, 0, 0) = +TraceBitMap_<>::NONE;
-    value(traceMatrix, 1, 0) = +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 2, 0) = +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 3, 0) = +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 0, 0) = TraceBitMap_<>::NONE;
+    value(traceMatrix, 1, 0) = TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 2, 0) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 3, 0) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
 
-    value(traceMatrix, 0, 1) = +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 1, 1) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 2, 1) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 3, 1) = +TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 0, 1) = TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 1, 1) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 2, 1) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 3, 1) = TraceBitMap_<>::HORIZONTAL_OPEN | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
 
-    value(traceMatrix, 0, 2) = +TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
-    value(traceMatrix, 1, 2) = +TraceBitMap_<>::VERTICAL_OPEN | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
-    value(traceMatrix, 2, 2) = +TraceBitMap_<>::DIAGONAL;
-    value(traceMatrix, 3, 2) = +TraceBitMap_<>::VERTICAL | +TraceBitMap_<>::DIAGONAL | +TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 0, 2) = TraceBitMap_<>::HORIZONTAL | TraceBitMap_<>::MAX_FROM_HORIZONTAL_MATRIX;
+    value(traceMatrix, 1, 2) = TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
+    value(traceMatrix, 2, 2) = TraceBitMap_<>::DIAGONAL;
+    value(traceMatrix, 3, 2) = TraceBitMap_<>::VERTICAL | TraceBitMap_<>::DIAGONAL | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX;
 
 
-    TDPTraceNavigator navigator;
-    _init(navigator, traceMatrix, DPBandConfig<BandOff>());
+    TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOff>()};
 
     DnaString str0 = "AC";
     DnaString str1 = "CCC";
@@ -475,8 +468,8 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_right_linear_gaps)
     dpScout._maxHostPosition = 11;
     _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
 
-    SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 2, 1, +TraceBitMap_<>::VERTICAL));
-    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 2, +TraceBitMap_<>::DIAGONAL));
+    SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 2, 1, TraceBitMap_<>::VERTICAL));
+    SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 2, TraceBitMap_<>::DIAGONAL));
 }
 
 SEQAN_DEFINE_TEST(test_align2_traceback_gaps_left_affine_gaps)
@@ -516,8 +509,7 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_left_affine_gaps)
         value(traceMatrix, 3, 2) = TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::DIAGONAL;
 
 
-        TDPTraceNavigator navigator;
-        _init(navigator, traceMatrix, DPBandConfig<BandOff>());
+        TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOff>()};
 
         DnaString str0 = "AC";
         DnaString str1 = "CCC";
@@ -527,8 +519,8 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_left_affine_gaps)
         _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
 
         // TODO(rmaerker): This is disabled by default for the affine gap costs.
-        SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 2, 1, +TraceBitMap_<>::VERTICAL));
-        SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 2, +TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 2, 1, TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 2, TraceBitMap_<>::DIAGONAL));
     }
 
     {   // Tests inner gaps.
@@ -563,8 +555,7 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_left_affine_gaps)
         value(traceMatrix, 2, 4) = TraceBitMap_<>::NONE;
         value(traceMatrix, 3, 4) = TraceBitMap_<>::DIAGONAL;
 
-        TDPTraceNavigator navigator;
-        _init(navigator, traceMatrix, DPBandConfig<BandOff>());
+        TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOff>()};
 
         DnaString str0 = "ACCA";
         DnaString str1 = "ACA";
@@ -574,9 +565,9 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_left_affine_gaps)
         _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
 
         // TODO(rmaerker): This is disabled by default for the affine gap costs.
-        SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 1, 2, +TraceBitMap_<>::DIAGONAL));
-        SEQAN_ASSERT_EQ(target[1], TTraceSegment(1, 1, 1, +TraceBitMap_<>::HORIZONTAL));
-        SEQAN_ASSERT_EQ(target[2], TTraceSegment(0, 0, 1, +TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 1, 2, TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(target[1], TTraceSegment(1, 1, 1, TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(target[2], TTraceSegment(0, 0, 1, TraceBitMap_<>::DIAGONAL));
     }
 
 }
@@ -617,8 +608,7 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_right_affine_gaps)
         value(traceMatrix, 3, 2) = TraceBitMap_<>::VERTICAL_OPEN | TraceBitMap_<>::MAX_FROM_VERTICAL_MATRIX | TraceBitMap_<>::DIAGONAL;
 
 
-        TDPTraceNavigator navigator;
-        _init(navigator, traceMatrix, DPBandConfig<BandOff>());
+        TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOff>()};
 
         DnaString str0 = "AC";
         DnaString str1 = "CCC";
@@ -627,8 +617,8 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_right_affine_gaps)
         dpScout._maxHostPosition = 11;
         _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
 
-        SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 2, 1, +TraceBitMap_<>::VERTICAL));
-        SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 2, +TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(target[0], TTraceSegment(2, 2, 1, TraceBitMap_<>::VERTICAL));
+        SEQAN_ASSERT_EQ(target[1], TTraceSegment(0, 0, 2, TraceBitMap_<>::DIAGONAL));
     }
 
     {   // Test inner gaps.
@@ -663,8 +653,7 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_right_affine_gaps)
         value(traceMatrix, 2, 4) = TraceBitMap_<>::NONE;
         value(traceMatrix, 3, 4) = TraceBitMap_<>::DIAGONAL;
 
-        TDPTraceNavigator navigator;
-        _init(navigator, traceMatrix, DPBandConfig<BandOff>());
+        TDPTraceNavigator navigator{traceMatrix, DPBandConfig<BandOff>()};
 
         DnaString str0 = "ACCA";
         DnaString str1 = "ACA";
@@ -674,9 +663,9 @@ SEQAN_DEFINE_TEST(test_align2_traceback_gaps_right_affine_gaps)
         _computeTraceback(target, navigator, dpScout, str0, str1, DPBandConfig<BandOff>(), TDPProfile());
 
         // TODO(rmaerker): This is disabled by default for the affine gap costs.
-        SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 2, 1, +TraceBitMap_<>::DIAGONAL));
-        SEQAN_ASSERT_EQ(target[1], TTraceSegment(2, 2, 1, +TraceBitMap_<>::HORIZONTAL));
-        SEQAN_ASSERT_EQ(target[2], TTraceSegment(0, 0, 2, +TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(target[0], TTraceSegment(3, 2, 1, TraceBitMap_<>::DIAGONAL));
+        SEQAN_ASSERT_EQ(target[1], TTraceSegment(2, 2, 1, TraceBitMap_<>::HORIZONTAL));
+        SEQAN_ASSERT_EQ(target[2], TTraceSegment(0, 0, 2, TraceBitMap_<>::DIAGONAL));
     }
 }
 
diff --git a/tests/align/test_mock.h b/tests/align/test_mock.h
new file mode 100644
index 0000000..96bd126
--- /dev/null
+++ b/tests/align/test_mock.h
@@ -0,0 +1,240 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#ifndef TESTS_ALIGN_TEST_MOCK_H_
+#define TESTS_ALIGN_TEST_MOCK_H_
+
+namespace impl
+{
+namespace test_align_mock
+{
+
+struct TestAlignSimdVariableLength_;
+using VariableLengthSimd = seqan::Tag<TestAlignSimdVariableLength_>;
+
+struct TestAlignSimdEqualLength_;
+using EqualLengthSimd = seqan::Tag<TestAlignSimdEqualLength_>;
+
+template <typename TAlphabet, typename TSimdLength>
+struct TestSequences_;
+
+template <>
+struct TestSequences_<seqan::Dna, EqualLengthSimd>
+{
+    using TSeq = seqan::String<seqan::Dna>;
+
+    static auto
+    getSequences()
+    {
+        seqan::StringSet<TSeq> set;
+        appendValue(set, "AGCGACTGCAAACATCAGATCAGAG");
+        appendValue(set, "TAATACTAGCATGCGATAAGTCCCT");
+        appendValue(set, "GGCACGTGGATGGTTTAGAGGAATC");
+        appendValue(set, "AGATTCAAGTCTGGTTAACCATCAA");
+        appendValue(set, "ACAGGTCTTGAGTCTAAAATTGTCG");
+        appendValue(set, "TCTCCTGCGTACGAGATGGAAATAC");
+        appendValue(set, "TAGGTAACTACAGGGACTCCGACGT");
+        appendValue(set, "TATGTACGTTGCTCCGTCAGAGGCG");
+
+        appendValue(set, "CCATTCAGGATCACGTTACCGCGAA");
+        appendValue(set, "AAAAAGGGACCAGGAGCTCTTCTCC");
+        appendValue(set, "CCTGCGGTCACGTCTATAGAAATTA");
+        appendValue(set, "CACCATTAACCCTCCTGAGAACCGG");
+        appendValue(set, "GAGGCGGGAATCCGTCACGTATGAG");
+        appendValue(set, "AAGGTATTTGCCCGATAATCAATAC");
+        appendValue(set, "CCCAGGCTTCTAACTTTTTCCACTC");
+        appendValue(set, "GCTTGAGCCGGCTAGGCCTTTCTGC");
+
+        appendValue(set, "ATCTCGGGTCCTGCCCAACCGGTCT");
+        appendValue(set, "AACAAGGGACCAGGAGCTCTTCTCC");
+        appendValue(set, "ACACGCTAATATAGCGAATCACCGA");
+        appendValue(set, "GAACCCGGCGCCACGCAATGGAACG");
+        appendValue(set, "TCCTTAACTCCGGCAGGCAATTAAA");
+        appendValue(set, "ACAGAAAAATAGGCGAATGAATCTT");
+        appendValue(set, "GGGAACGTATGTATAACGCAAAAAA");
+        appendValue(set, "TTCTCTGTGTATCGAAGAATGGCCT");
+
+        appendValue(set, "CCGAAGTTTCGATGGACTGGTGCCA");
+        appendValue(set, "ACGCGCAGGCATAGTTTTAGGAGAA");
+        appendValue(set, "TTATTCGGGGGCAGTGACAACCAAC");
+
+        seqan::StringSet<TSeq>  set2(set);
+        std::sort(seqan::begin(set2, seqan::Standard()), seqan::end(set2, seqan::Standard()),
+                  [](auto& strA, auto& strB){ return seqan::isLess(strA, strB); });
+        return std::make_tuple(set, set2);
+    }
+};
+
+template <>
+struct TestSequences_<seqan::Dna, VariableLengthSimd>
+{
+    using TSeq = seqan::String<seqan::Dna>;
+
+    static auto
+    getSequences()
+    {
+        seqan::StringSet<TSeq> set;
+        appendValue(set, "AGCGACTGCAAACATCAGATCAGAGGTAGAG");
+        appendValue(set, "TAATACTAGCATGCGATAAGTCCCT");
+        appendValue(set, "GGCACGTGTGGTTTAGAGGAATC");
+        appendValue(set, "AGATTCAAGTCTGGTTAACCATCAA");
+        appendValue(set, "ACAGGTCTTGAGTCTAAAATTGTCGAA");
+        appendValue(set, "TCTCCTGCGTACGAGATGGAAATAC");
+        appendValue(set, "TAGGTAACTACAGGGACACGT");
+        appendValue(set, "TATGTACGTCTCCGTCAGAGGCG");
+
+        appendValue(set, "CCATTCAGGATCACGTTACCGCGAAGTACCC");
+        appendValue(set, "AAGGGACCAGGAGCTCTTCTCC");
+        appendValue(set, "CCTGCGGTCACGTCTATAGAAATT");
+        appendValue(set, "CACCATTAACCCTCCTGAGAACCGAGTAGG");
+        appendValue(set, "GAGGCGGGAATCCGTCACGTATGAG");
+        appendValue(set, "AAGGTATTTGCCCGATAATCAATACGATGAGATAGAGAGATAGAATAGAGAAGGGACCGCGCATGACTACGATCGACTGACTACGA");
+        appendValue(set, "CGAGTATATCGAGAGAGGTCACG");
+        appendValue(set, "GCTTGAGCCGGCTAGGCTCTGC");
+
+        appendValue(set, "ATCTCGGGTCCTGCCAACCGGTCT");
+        appendValue(set, "AAAAAGGGACCAGGAGCTCTTCTCC");
+        appendValue(set, "ACACGCTAATATAGCGAATCACCGA");
+        appendValue(set, "AATGGAACG");
+        appendValue(set, "TCCTTAACTCCGGCAGGCAATTATACCGGACTGACACTTAAA");
+        appendValue(set, "ACAGAAAAATAGGCGAATGAAACACTCTT");
+        appendValue(set, "GGGAACGTATGTATAACGCAAAAA");
+        appendValue(set, "TTCTCTGTGTATCGAAGAATGCT");
+
+        appendValue(set, "CCGAAGTTTCGATGGATGGATTCCACACACCTGGTGCCA");
+        appendValue(set, "ACGCGCAGGCATAGTTGGAGAA");
+        appendValue(set, "TTATTCGGGGGCAGTGACAACACTTAGCGACTAC");
+
+        auto set2(set);
+        std::sort(seqan::begin(set2, seqan::Standard()), seqan::end(set2, seqan::Standard()),
+                  [](auto& strA, auto& strB){ return seqan::isLess(strA, strB); });
+        return std::make_tuple(set, set2);
+    }
+};
+
+template <>
+struct TestSequences_<seqan::AminoAcid, EqualLengthSimd>
+{
+    using TSeq = seqan::String<seqan::AminoAcid>;
+
+    static auto
+    getSequences()
+    {
+        seqan::StringSet<TSeq> set;
+        appendValue(set, "FNQSAEYPDISLHCGVLKWRATLGT");
+        appendValue(set, "EIKSDVLLHRPGNIGMQVAESYFAT");
+        appendValue(set, "PIIMWSMKNRTIERLPTGVLMISHT");
+        appendValue(set, "FMATNEKVHCACGADYQMIIDCNEA");
+        appendValue(set, "MFHQTSNANWMFVSNKFHIKFGTLD");
+        appendValue(set, "SNEMGQCFPHEPACFFDKDFRLFIN");
+        appendValue(set, "FPWAHYVVHTLREHRKDANHRSTSY");
+        appendValue(set, "QYRNTESMGCEMRCFTETIMIAGVA");
+
+        appendValue(set, "VVRMDGKEVLKQHVPTYADKHPTGQ");
+        appendValue(set, "TMLKWCEWCFAEFPPFASEPKFPPN");
+        appendValue(set, "GTWGWVDGVHHTMGEQCGPGRACWG");
+        appendValue(set, "ECDFQTWYFYCVNQEIFELFICCMG");
+        appendValue(set, "KRRELNGQERGGWWTVDGPGVSMGT");
+        appendValue(set, "CWAAHYVCWRTKQKQLVAFQRLNCI");
+        appendValue(set, "NRLVGFQIHCFLIRCVEPGQTHTID");
+        appendValue(set, "AYYVRGFMMGQMYGRPVILMTFTKP");
+
+        appendValue(set, "SFTQPVELHIPHYWWHLAYFMIMFY");
+        appendValue(set, "PMNKMFDFNNHQDLLTFTKRFPTPW");
+        appendValue(set, "VIPMIYHDWSIISALMMQKDIYYIA");
+        appendValue(set, "TPGMWGMATLTGNFNSIFVSKYVKN");
+        appendValue(set, "GKELWGMVIARAGMAVQNMYSRDTF");
+        appendValue(set, "VHASDLYAKCYSNCVYQENIDIAEV");
+        appendValue(set, "KQSGTLSGPQYWENVHRVLEDYPKE");
+        appendValue(set, "DPHGYCFYEGTFAWDVEVHEFNNKD");
+
+        appendValue(set, "NMQDVIGGKSLAQHSSVTYKAQQEH");
+        appendValue(set, "CQTPRWECSLNFDEKEAADLMIDVS");
+        appendValue(set, "PMMDLDHCMLIECLRPHNRDNCARH");
+
+        decltype(set) set2(set);
+        std::sort(seqan::begin(set2, seqan::Standard()), seqan::end(set2, seqan::Standard()),
+                  [](auto& strA, auto& strB){ return seqan::isLess(strA, strB); });
+        return std::make_tuple(set, set2);
+    }
+};
+
+template <>
+struct TestSequences_<seqan::AminoAcid, VariableLengthSimd>
+{
+    using TSeq = seqan::String<seqan::AminoAcid>;
+
+    static auto
+    getSequences()    {
+        seqan::StringSet<TSeq> set;
+        appendValue(set, "FNQSAEYPDISHCGVMQLKWRATLGT");
+        appendValue(set, "EIKSDVLLHRWSMKNPGNILMIDVGMQVAESYFAT");
+        appendValue(set, "PIIMWSMKNRTIEPTGLMISHT");
+        appendValue(set, "FMATNEKVHCACGWSMKNADLMIDVYQMIIDCNEA");
+        appendValue(set, "MWSMKNFHQTSNANWMFVSNMQKFHIKFGTLD");
+        appendValue(set, "SNEGQCFPHEPACFWSMKFDKDFRLFIN");
+        appendValue(set, "FPWAHYVVHTLREHMQRKDANHRSTSY");
+        appendValue(set, "QYRNTWSMKNESMGCEMRFLMIVTETIMIAGVA");
+
+        appendValue(set, "VVRMDGKEVLWSMKNKQHVPTYADKHPTGQ");
+        appendValue(set, "TMLKWCEWCFALMIDVEFPPFASEPKFPPN");
+        appendValue(set, "GTWGVDGVHHWSMWSMKNLMIDVTMGEQCGPGRACWG");
+        appendValue(set, "ECDFQTWYFYCVNQMQEIFELFICCMG");
+        appendValue(set, "KRREWSMKNLNGQERGGWWTVDGPGVSMGT");
+        appendValue(set, "CWAAHYCWRWWSMKNSMKNTKLMIDVQMQKQLVAFQRLNCI");
+        appendValue(set, "NRLVGFQIHCFIRCVEPGQTHTID");
+        appendValue(set, "AYYVRGFMMGQMMQYGRPVILMTFTKP");
+
+        appendValue(set, "SFTQPVELHIPHYWLMIDVWHLAYFMIMFY");
+        appendValue(set, "PMNKMFDFNHQMQDLLTFTKPTPW");
+        appendValue(set, "VIPMIYHDWSIISALMMLMIDVQKDIYYIA");
+        appendValue(set, "TPGMWGMATLTGMQNFNSFVSKYVKN");
+        appendValue(set, "GKELWGMVIARAGMAVQNLMIDVMYSRDTF");
+        appendValue(set, "VHASDLWSNYAKCYSNCVYQEIDIAEV");
+        appendValue(set, "KQSGTLSMQGPYWENVHRVLLMIDVEDYPKE");
+        appendValue(set, "DPHGYCFMQYEGTFAWDVEVHEFNNKD");
+
+        appendValue(set, "NMQDVIGGKSLAQHSSVTYAQQEH");
+        appendValue(set, "CQTPRWECMQSLNFDEKEAADLMIDVS");
+        appendValue(set, "PMMDLDWSMKNMLIECLRPHNRMQDNLMIDVCARH");
+
+        auto set2(set);
+        std::sort(seqan::begin(set2, seqan::Standard()), seqan::end(set2, seqan::Standard()),
+                  [](auto& strA, auto& strB){ return seqan::isLess(strA, strB); });
+        return std::make_tuple(set, set2);
+    }
+};
+} // namespace test_align_mock
+} // namespace impl
+#endif // TEST_MOCK_H_
diff --git a/tests/align_parallel/CMakeLists.txt b/tests/align_parallel/CMakeLists.txt
new file mode 100644
index 0000000..df770f5
--- /dev/null
+++ b/tests/align_parallel/CMakeLists.txt
@@ -0,0 +1,78 @@
+# ===========================================================================
+#                  SeqAn - The Library for Sequence Analysis
+# ===========================================================================
+# File: /tests/align_parallel/CMakeLists.txt
+#
+# CMakeLists.txt file for the align_parallel module tests.
+# ===========================================================================
+
+cmake_minimum_required (VERSION 3.0.0)
+project (seqan_tests_align_parallel CXX)
+message (STATUS "Configuring tests/align_parallel")
+
+# ----------------------------------------------------------------------------
+# Dependencies
+# ----------------------------------------------------------------------------
+
+set (ALIGN_PARALLEL_SIMD_TEST TRUE CACHE INTERNAL "Whether to build test_align_parallel.")
+# workaround a bug in llvm35 on FreeBSD
+if ((${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") AND
+    (COMPILER_CLANG) AND
+    (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6.0))
+    set (ALIGN_PARALLEL_SIMD_TEST FALSE CACHE INTERNAL "Whether to build test_align_parallel.")
+endif ()
+
+# Increase recursive template instantiation depth for clang compiler.
+if (COMPILER_CLANG)
+    set(SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -ftemplate-depth=1024")
+endif ()
+
+# ----------------------------------------------------------------------------
+# 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_align_parallel_data_structures
+                test_align_parallel_data_structures.cpp
+                test_align_wavefront_task_scheduler.h
+                test_align_wavefront_alignment_scheduler.h
+                test_align_wavefront_intermediate_dp_result.h
+                test_align_wavefront_alignment_thread_local.h)
+
+add_executable (test_align_parallel_algorithm
+                test_align_parallel_algorithm.cpp
+                test_align_parallel_wavefront_alignment.h)
+
+add_executable (test_align_parallel_interface
+                test_align_parallel_interface.cpp
+                test_align_parallel_interface.h
+                ../align/test_mock.h)
+
+# Add dependencies found by find_package (SeqAn).
+target_link_libraries (test_align_parallel_data_structures ${SEQAN_LIBRARIES})
+
+# Add dependencies found by find_package (SeqAn).
+target_link_libraries (test_align_parallel_algorithm ${SEQAN_LIBRARIES})
+
+# Add dependencies found by find_package (SeqAn).
+target_link_libraries (test_align_parallel_interface ${SEQAN_LIBRARIES})
+
+# Add CXX flags found by find_package (SeqAn).
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SEQAN_CXX_FLAGS}")
+
+# ----------------------------------------------------------------------------
+# Register with CTest
+# ----------------------------------------------------------------------------
+
+add_test (NAME test_align_parallel_data_structures COMMAND $<TARGET_FILE:test_align_parallel_data_structures>)
+if (ALIGN_PARALLEL_SIMD_TEST)
+    include (SeqAnSimdUtility)
+    add_simd_platform_tests(test_align_parallel_interface)
+    add_simd_platform_tests(test_align_parallel_algorithm)
+endif ()
diff --git a/tests/align/test_align_simd.cpp b/tests/align_parallel/test_align_parallel_algorithm.cpp
similarity index 75%
copy from tests/align/test_align_simd.cpp
copy to tests/align_parallel/test_align_parallel_algorithm.cpp
index 405b6b6..987ff7f 100644
--- a/tests/align/test_align_simd.cpp
+++ b/tests/align_parallel/test_align_parallel_algorithm.cpp
@@ -29,15 +29,23 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: René Rahn <rene.rahn at fu-berlin.de>
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
 #include <seqan/basic.h>
-#include <seqan/stream.h>
 
-#include "test_align_simd.h"
+#include "test_align_parallel_wavefront_alignment.h"
 
-int main(int argc, char const ** argv) {
-    seqan::TestSystem::init(argc, argv);
-    return seqan::TestSystem::runAll();
+SEQAN_BEGIN_TESTSUITE(test_align_parallel_algorithm)
+{
+    // -----------------------------------------------------------------------
+    // Test single wavefront alignment.
+    // -----------------------------------------------------------------------
+
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_single_global_alignment);
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_multiple_global_alignment);
+#ifdef SEQAN_SIMD_ENABLED
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_multiple_global_alignment_simd);
+#endif
 }
+SEQAN_END_TESTSUITE
diff --git a/tests/multiple_translation_units/test_multiple_translation_units.cpp b/tests/align_parallel/test_align_parallel_data_structures.cpp
similarity index 50%
copy from tests/multiple_translation_units/test_multiple_translation_units.cpp
copy to tests/align_parallel/test_align_parallel_data_structures.cpp
index 650820e..f412653 100644
--- a/tests/multiple_translation_units/test_multiple_translation_units.cpp
+++ b/tests/align_parallel/test_align_parallel_data_structures.cpp
@@ -29,56 +29,47 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: Jochen Singer <jochen.singer at fu-berlin.de>
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#include <seqan/align.h>
-#include <seqan/align_extend.h>
-#include <seqan/align_profile.h>
-#include <seqan/align_split.h>
-#include <seqan/alignment_free.h>
-#include <seqan/arg_parse.h>
-#include <seqan/bam_io.h>
 #include <seqan/basic.h>
-#include <seqan/bed_io.h>
-#include <seqan/consensus.h>
-#include <seqan/file.h>
-#include <seqan/find.h>
-#include <seqan/gff_io.h>
-#include <seqan/graph_algorithms.h>
-#include <seqan/graph_align.h>
-#include <seqan/graph_msa.h>
-#include <seqan/graph_types.h>
-#include <seqan/index.h>
-#include <seqan/journaled_set.h>
-#include <seqan/map.h>
-#include <seqan/math.h>
-#include <seqan/modifier.h>
-#include <seqan/parallel.h>
-#include <seqan/parse_lm.h>
-#include <seqan/pipe.h>
-#include <seqan/platform.h>
-#include <seqan/random.h>
-#include <seqan/realign.h>
-#include <seqan/reduced_aminoacid.h>
-#include <seqan/roi_io.h>
-#include <seqan/score.h>
-#include <seqan/seeds.h>
-#include <seqan/seq_io.h>
-#include <seqan/sequence.h>
-#include <seqan/sequence_journaled.h>
-#include <seqan/simple_intervals_io.h>
-#include <seqan/statistics.h>
-#include <seqan/store.h>
-#include <seqan/stream.h>
-#include <seqan/system.h>
-#include <seqan/translation.h>
-#include <seqan/ucsc_io.h>
-#include <seqan/vcf_io.h>
-#include <seqan/version.h>
 
-// This test simply checks whether all functions are inline or templates.
-SEQAN_BEGIN_TESTSUITE(test_multiple_translation_units)
+#include "test_align_wavefront_task_scheduler.h"
+#include "test_align_wavefront_alignment_scheduler.h"
+#include "test_align_wavefront_intermediate_dp_result.h"
+#include "test_align_wavefront_alignment_thread_local.h"
+
+SEQAN_BEGIN_TESTSUITE(test_align_parallel_data_structures)
 {
+    // -----------------------------------------------------------------------
+    // Test wavefront task scheduler.
+    // -----------------------------------------------------------------------
+
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_task_scheduler_construct);
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_task_scheduler_async);
+
+    // -----------------------------------------------------------------------
+    // Test wavefront alignment scheduler.
+    // -----------------------------------------------------------------------
+
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_alignment_scheduler_construct);
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_alignment_scheduler_async);
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_alignment_scheduler_async_with_exception);
+
+    // -----------------------------------------------------------------------
+    // Test WavefrontAlignmentResult
+    // -----------------------------------------------------------------------
+
+    SEQAN_CALL_TEST(test_align_parallel_intermediate_dp_result_construct);
+    SEQAN_CALL_TEST(test_align_parallel_intermediate_dp_result_update_max);
+    SEQAN_CALL_TEST(test_align_parallel_intermediate_dp_result_clear);
+
+    // -----------------------------------------------------------------------
+    // Test WavefrontAlignmentThreadLocalStorage
+    // -----------------------------------------------------------------------
+
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_alignment_thread_local_storage_construt);
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_alignment_thread_local_storage_cache);
+    SEQAN_CALL_TEST(test_align_parallel_wavefront_alignment_thread_local_storage_intermediate);
 }
 SEQAN_END_TESTSUITE
diff --git a/tests/align/test_align_simd.cpp b/tests/align_parallel/test_align_parallel_interface.cpp
similarity index 98%
copy from tests/align/test_align_simd.cpp
copy to tests/align_parallel/test_align_parallel_interface.cpp
index 405b6b6..4407c1a 100644
--- a/tests/align/test_align_simd.cpp
+++ b/tests/align_parallel/test_align_parallel_interface.cpp
@@ -35,7 +35,7 @@
 #include <seqan/basic.h>
 #include <seqan/stream.h>
 
-#include "test_align_simd.h"
+#include "test_align_parallel_interface.h"
 
 int main(int argc, char const ** argv) {
     seqan::TestSystem::init(argc, argv);
diff --git a/tests/align_parallel/test_align_parallel_interface.h b/tests/align_parallel/test_align_parallel_interface.h
new file mode 100644
index 0000000..2345f05
--- /dev/null
+++ b/tests/align_parallel/test_align_parallel_interface.h
@@ -0,0 +1,168 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+// #define DP_PARALLEL_SHOW_PROGRESS // Enable when debugging.
+
+#include <seqan/align_parallel.h>
+
+#include "../align/test_mock.h"
+
+namespace test_align_parallel
+{
+
+template <typename TSets, typename TResults, typename ...TParams>
+inline void
+validateGlobal(TSets const & sets,
+               TResults const & res,
+               TParams && ...params)
+{
+    auto z = makeZipView(std::get<0>(sets), std::get<1>(sets), res);
+
+    for (auto && inst : z)
+    {
+        auto tmp = globalAlignmentScore(std::get<0>(inst), std::get<1>(inst), std::forward<TParams>(params)...);
+        SEQAN_ASSERT_EQ(tmp, std::get<2>(inst));
+    }
+}
+
+template <typename TSets, typename TResults, typename ...TParams>
+inline void
+validateLocal(TSets const & sets,
+              TResults const & res,
+              TParams && ...params)
+{
+    auto z = makeZipView(std::get<0>(sets), std::get<1>(sets), res);
+
+    for (auto && inst : z)
+    {
+        auto tmp = localAlignmentScore(std::get<0>(inst), std::get<1>(inst), std::forward<TParams>(params)...);
+        SEQAN_ASSERT_EQ(tmp, std::get<2>(inst));
+    }
+}
+
+}  // namespace test_align_parallel
+
+// ----------------------------------------------------------------------------
+// Class SimdAlignTest
+// ----------------------------------------------------------------------------
+
+// Common test class instance, which stores the types to be accessed.
+template <typename TTuple>
+class ParallelAlignInterfaceTest : public seqan::Test
+{
+public:
+    using TExecPolicy = std::tuple_element_t<0, TTuple>;
+};
+
+// ----------------------------------------------------------------------------
+// Configuration of typed tests for global alignment.
+// ----------------------------------------------------------------------------
+
+template <typename T>
+class ParallelAlignInterfaceTestCommon : public ParallelAlignInterfaceTest<T>
+{};
+
+typedef
+        seqan::TagList<std::tuple<seqan::ExecutionPolicy<seqan::Serial,                                             seqan::Serial>>,
+        seqan::TagList<std::tuple<seqan::ExecutionPolicy<seqan::Parallel,                                           seqan::Serial>>,
+        seqan::TagList<std::tuple<seqan::ExecutionPolicy<seqan::WavefrontAlignment<>,                               seqan::Serial>>,
+        seqan::TagList<std::tuple<seqan::ExecutionPolicy<seqan::WavefrontAlignment<seqan::BlockOffsetOptimization>, seqan::Serial>>
+#ifdef SEQAN_SIMD_ENABLED
+        ,
+        seqan::TagList<std::tuple<seqan::ExecutionPolicy<seqan::Serial,                                             seqan::Vectorial>>,
+        seqan::TagList<std::tuple<seqan::ExecutionPolicy<seqan::Parallel,                                           seqan::Vectorial>>,
+        seqan::TagList<std::tuple<seqan::ExecutionPolicy<seqan::WavefrontAlignment<>,                               seqan::Vectorial>>,
+        seqan::TagList<std::tuple<seqan::ExecutionPolicy<seqan::WavefrontAlignment<seqan::BlockOffsetOptimization>, seqan::Vectorial>>
+        > > > >
+#endif // SEQAN_SIMD_ENABLED
+        > > > > ParallelAlignInterfaceTestCommonTypes;
+
+SEQAN_TYPED_TEST_CASE(ParallelAlignInterfaceTestCommon, ParallelAlignInterfaceTestCommonTypes);
+
+SEQAN_TYPED_TEST(ParallelAlignInterfaceTestCommon, Global_Score)
+{
+    using namespace seqan;
+    using TExecPolicy = typename TestFixture::TExecPolicy;
+
+    auto sets = ::impl::test_align_mock::TestSequences_<Dna, ::impl::test_align_mock::EqualLengthSimd>::getSequences();
+
+    Score<int, Simple> scoreLinear(4, -2, -4);
+    TExecPolicy execPolicy;
+    setNumThreads(execPolicy, 4);
+    auto score = globalAlignmentScore(execPolicy, std::get<0>(sets), std::get<1>(sets), scoreLinear);
+
+    test_align_parallel::validateGlobal(sets, score, scoreLinear);
+
+    Score<int, Simple> scoreAffine(4, -2, -4, -10);
+    score = globalAlignmentScore(execPolicy, std::get<0>(sets), std::get<1>(sets), scoreAffine);
+    test_align_parallel::validateGlobal(sets, score, scoreAffine);
+}
+
+SEQAN_TYPED_TEST(ParallelAlignInterfaceTestCommon, Semi_Global_Score)
+{
+    using namespace seqan;
+    using TExecPolicy = typename TestFixture::TExecPolicy;
+
+    auto sets = ::impl::test_align_mock::TestSequences_<Dna, ::impl::test_align_mock::EqualLengthSimd>::getSequences();
+
+    Score<int, Simple> scoreLinear(4, -2, -4);
+    TExecPolicy execPolicy;
+    setNumThreads(execPolicy, 4);
+    auto score = globalAlignmentScore(execPolicy, std::get<0>(sets), std::get<1>(sets), scoreLinear, AlignConfig<true, false, false, true>());
+
+    test_align_parallel::validateGlobal(sets, score, scoreLinear, AlignConfig<true, false, false, true>());
+
+    Score<int, Simple> scoreAffine(4, -2, -4, -10);
+    score = globalAlignmentScore(execPolicy, std::get<0>(sets), std::get<1>(sets), scoreAffine, AlignConfig<true, false, false, true>());
+    test_align_parallel::validateGlobal(sets, score, scoreAffine, AlignConfig<true, false, false, true>());
+}
+
+SEQAN_TYPED_TEST(ParallelAlignInterfaceTestCommon, Local_Score)
+{
+    using namespace seqan;
+    using TExecPolicy = typename TestFixture::TExecPolicy;
+
+    auto sets = ::impl::test_align_mock::TestSequences_<Dna, ::impl::test_align_mock::EqualLengthSimd>::getSequences();
+
+    Score<int, Simple> scoreLinear(4, -2, -4);
+    TExecPolicy execPolicy;
+    setNumThreads(execPolicy, 4);
+    auto score = localAlignmentScore(execPolicy, std::get<0>(sets), std::get<1>(sets), scoreLinear);
+
+    test_align_parallel::validateLocal(sets, score, scoreLinear);
+
+    Score<int, Simple> scoreAffine(4, -2, -4, -10);
+    score = localAlignmentScore(execPolicy, std::get<0>(sets), std::get<1>(sets), scoreAffine);
+    test_align_parallel::validateLocal(sets, score, scoreAffine);
+}
diff --git a/tests/align_parallel/test_align_parallel_wavefront_alignment.h b/tests/align_parallel/test_align_parallel_wavefront_alignment.h
new file mode 100644
index 0000000..0f40da6
--- /dev/null
+++ b/tests/align_parallel/test_align_parallel_wavefront_alignment.h
@@ -0,0 +1,183 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#include <seqan/align_parallel.h>
+
+namespace test_align_parallel
+{
+struct DPTestConfig : public seqan::DPTraits::GlobalAffine
+{
+    using TTracebackType = seqan::TracebackOff;
+};
+}  // namespace test_align_parallel
+
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_single_global_alignment)
+{
+    using namespace seqan;
+    // We need to be able to construct a thread pool.
+
+    // Define the traits object based on the settings.
+    // now we want to define a WavefrontAlignmentTask connecting all the components together.
+    DnaString seqH = "GGTTTTGTTTGATGGAGAATTGCGCAGAGGGGTTATATCTGCGTGAGGATCTGTCACTCGGCGGTGTGGG"
+                     "ATACCTCCCTGCTAAGGCGGGTTGAGTGATGTTCCCTCGGACTGGGGACCGCTGGCTTGCGAGCTATGTC"
+                     "CGCTACTCTCAGTACTACACTCTCATTTGAGCCCCCGCTCAGTTTGCTAGCAGAACCCGGCACATGGTTC"
+                     "GCCGATACTATGGATTTTCTAAAGAAACACTCTGTTAGGTGGTATGAGTCATGACGCACGCAGGGAGAGG"
+                     "CTAAGGCTTATGCTATGCTGATCTCCGTGAATGTCTATCATTCCTCTGCAGGACCC";
+
+    DnaString seqV = "ACAGAGCGCGTACTGTCTGACGACGTATCCGCGCGGACTAGAAGGCTGGTGCCTCGTCCAACAAATAGAT"
+                     "ACAGAAATCCACCGAAGTAAAGATCTCCAATTGTGGCACCACCAGGTGGCCACCACTCTTTGAAGTGAGG"
+                     "AGACTTGCTTTACGTGTTTGTTCAGCCCGAGCTTTCGCTCGCACTGGAACACTGGTGTTTCGTCCTTTCG"
+                     "GACTCATCAGTCAAGGTACGCACCTTGAGACACCGGGAAACAATCGATCAATCTTTCACAGAGCAACGAG"
+                     "TTCGCTACTCTTGCAAAAGATCGACTTCCTATTTCGTGGATA";
+
+    using TDPSettings = DPSettings<Score<int, Simple>, test_align_parallel::DPTestConfig>;
+    TDPSettings settings;
+    settings.scoringScheme = Score<int, Simple>{2, -2, -1, -11};
+
+    WavefrontAlignmentTask<DnaString, DnaString, TDPSettings> task{seqH, seqV, settings, 37};
+
+    using TThreadLocal = typename WavefrontAlignmentTaskConfig<TDPSettings>::TThreadLocal;
+
+    EnumerableThreadLocal<TThreadLocal> tls{TThreadLocal{1}};
+
+    WavefrontTaskScheduler scheduler(1, 1);
+    lockWriting(scheduler);
+    waitForWriters(scheduler);
+
+    WavefrontAlignmentExecutor<WavefrontTaskScheduler, decltype(tls)> executor{&scheduler, &tls};
+
+    int testScore{};
+    task(0, executor, [&](auto const /*id*/, auto const & score)
+    {
+        testScore = score;
+    });
+
+    SEQAN_ASSERT_EQ(globalAlignmentScore(seqH, seqV, settings.scoringScheme, AlignConfig<false, false, false, false>()), testScore);
+    unlockWriting(scheduler);
+}
+
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_multiple_global_alignment)
+{
+    using namespace seqan;
+
+    DnaString seqH = "GGTTTTGTTTGATGGAGAATTGCGCAGAGGGGTTATATCTGCGTGAGGATCTGTCACTCGGCGGTGTGGG"
+                     "ATACCTCCCTGCTAAGGCGGGTTGAGTGATGTTCCCTCGGACTGGGGACCGCTGGCTTGCGAGCTATGTC"
+                     "CGCTACTCTCAGTACTACACTCTCATTTGAGCCCCCGCTCAGTTTGCTAGCAGAACCCGGCACATGGTTC"
+                     "GCCGATACTATGGATTTTCTAAAGAAACACTCTGTTAGGTGGTATGAGTCATGACGCACGCAGGGAGAGG"
+                     "CTAAGGCTTATGCTATGCTGATCTCCGTGAATGTCTATCATTCCTCTGCAGGACCC";
+
+    DnaString seqV = "ACAGAGCGCGTACTGTCTGACGACGTATCCGCGCGGACTAGAAGGCTGGTGCCTCGTCCAACAAATAGAT"
+                     "ACAGAAATCCACCGAAGTAAAGATCTCCAATTGTGGCACCACCAGGTGGCCACCACTCTTTGAAGTGAGG"
+                     "AGACTTGCTTTACGTGTTTGTTCAGCCCGAGCTTTCGCTCGCACTGGAACACTGGTGTTTCGTCCTTTCG"
+                     "GACTCATCAGTCAAGGTACGCACCTTGAGACACCGGGAAACAATCGATCAATCTTTCACAGAGCAACGAG"
+                     "TTCGCTACTCTTGCAAAAGATCGACTTCCTATTTCGTGGATA";
+
+    StringSet<DnaString> setH;
+    StringSet<DnaString> setV;
+
+    for (unsigned i = 0; i < 100; ++i)
+    {
+        appendValue(setH, (i % 2 == 0) ? seqV : seqH);
+        appendValue(setV, (i % 5 == 0) ? seqH : seqV);
+    }
+
+    ExecutionPolicy<WavefrontAlignment<>, Serial> execPolicy;
+    setNumThreads(execPolicy, 4);
+    setParallelAlignments(execPolicy, 8);
+    setBlockSize(execPolicy, 56);
+
+    using TDPSettings = DPSettings<Score<int, Simple>, test_align_parallel::DPTestConfig>;
+    TDPSettings settings;
+    settings.scoringScheme = Score<int, Simple>{2, -2, -1, -11};
+
+    std::vector<int> alignScores(length(setH), std::numeric_limits<int>::min());
+
+    impl::alignExecBatch(execPolicy, setH, setV, settings, [&](auto const id, auto const score)
+    {
+        alignScores[id] = score;
+    });
+
+    for (unsigned i = 0; i < length(setH); ++i)
+    {
+        SEQAN_ASSERT_EQ(globalAlignmentScore(setH[i], setV[i], settings.scoringScheme, AlignConfig<false, false, false, false>()), alignScores[i]);
+    }
+}
+
+#ifdef SEQAN_SIMD_ENABLED
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_multiple_global_alignment_simd)
+{
+    using namespace seqan;
+
+    DnaString seqH = "GGTTTTGTTTGATGGAGAATTGCGCAGAGGGGTTATATCTGCGTGAGGATCTGTCACTCGGCGGTGTGGG"
+    "ATACCTCCCTGCTAAGGCGGGTTGAGTGATGTTCCCTCGGACTGGGGACCGCTGGCTTGCGAGCTATGTC"
+    "CGCTACTCTCAGTACTACACTCTCATTTGAGCCCCCGCTCAGTTTGCTAGCAGAACCCGGCACATGGTTC"
+    "GCCGATACTATGGATTTTCTAAAGAAACACTCTGTTAGGTGGTATGAGTCATGACGCACGCAGGGAGAGG"
+    "CTAAGGCTTATGCTATGCTGATCTCCGTGAATGTCTATCATTCCTCTGCAGGACCC";
+
+    DnaString seqV = "ACAGAGCGCGTACTGTCTGACGACGTATCCGCGCGGACTAGAAGGCTGGTGCCTCGTCCAACAAATAGAT"
+    "ACAGAAATCCACCGAAGTAAAGATCTCCAATTGTGGCACCACCAGGTGGCCACCACTCTTTGAAGTGAGG"
+    "AGACTTGCTTTACGTGTTTGTTCAGCCCGAGCTTTCGCTCGCACTGGAACACTGGTGTTTCGTCCTTTCG"
+    "GACTCATCAGTCAAGGTACGCACCTTGAGACACCGGGAAACAATCGATCAATCTTTCACAGAGCAACGAG"
+    "TTCGCTACTCTTGCAAAAGATCGACTTCCTATTTCGTGGATA";
+
+    StringSet<DnaString> setH;
+    StringSet<DnaString> setV;
+
+    for (unsigned i = 0; i < 100; ++i)
+    {
+        appendValue(setH, (i % 2 == 0) ? seqV : seqH);
+        appendValue(setV, (i % 5 == 0) ? seqH : seqV);
+    }
+
+    ExecutionPolicy<WavefrontAlignment<>, Vectorial> execPolicy;
+    setNumThreads(execPolicy, 4);
+    setParallelAlignments(execPolicy, 8);
+    setBlockSize(execPolicy, 56);
+
+    using TDPSettings = DPSettings<Score<int, Simple>, test_align_parallel::DPTestConfig>;
+    TDPSettings settings;
+    settings.scoringScheme = Score<int, Simple>{2, -2, -1, -11};
+
+    std::vector<int> alignScores(length(setH), std::numeric_limits<int>::min());
+    impl::alignExecBatch(execPolicy, setH, setV, settings, [&](auto const id, auto const score)
+                         {
+                             alignScores[id] = score;
+                         });
+
+    for (unsigned i = 0; i < length(setH); ++i)
+    {
+        SEQAN_ASSERT_EQ(globalAlignmentScore(setH[i], setV[i], settings.scoringScheme, AlignConfig<false, false, false, false>()), alignScores[i]);
+    }
+}
+#endif
diff --git a/tests/align_parallel/test_align_wavefront_alignment_scheduler.h b/tests/align_parallel/test_align_wavefront_alignment_scheduler.h
new file mode 100644
index 0000000..01cbc0d
--- /dev/null
+++ b/tests/align_parallel/test_align_wavefront_alignment_scheduler.h
@@ -0,0 +1,267 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#include <seqan/align_parallel.h>
+
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_alignment_scheduler_construct)
+{
+    using namespace seqan;
+
+    // We need to be able to construct a thread pool.
+    SEQAN_ASSERT(std::is_default_constructible<WavefrontAlignmentScheduler>::value);
+    SEQAN_ASSERT(!std::is_copy_constructible<WavefrontAlignmentScheduler>::value);
+    SEQAN_ASSERT(!std::is_move_constructible<WavefrontAlignmentScheduler>::value);
+    SEQAN_ASSERT(!std::is_copy_assignable<WavefrontAlignmentScheduler>::value);
+    SEQAN_ASSERT(!std::is_move_assignable<WavefrontAlignmentScheduler>::value);
+
+    {  // Default construction and termination.
+        try
+        {
+            WavefrontAlignmentScheduler scheduler{};
+        }
+        catch(...)
+        {
+            SEQAN_ASSERT_FAIL("Failed to default construct scheduler!");
+        }
+    }
+
+    {  // Construction with some parameters and some values.
+
+        try
+        {
+            WavefrontAlignmentScheduler scheduler{4, 2};
+        }
+        catch(...)
+        {
+            SEQAN_ASSERT_FAIL("Failed to default construct scheduler!");
+        }
+    }
+}
+
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_alignment_scheduler_async)
+{
+    using namespace seqan;
+
+    using TTask = SchedulerTraits<WavefrontAlignmentScheduler>::TTask;
+
+    WavefrontAlignmentScheduler scheduler{8,2};
+
+    std::vector<uint16_t>  calledIds{0, 0, 0, 0, 0, 0, 0, 0};
+    bool isRecycled{false};
+    std::mutex mutexSetBool;
+
+    TTask t = [&](uint16_t const id)
+    {
+        // Now how can we spawn a test to the underlying scheduler.
+        auto & _taskScheduler = taskScheduler(scheduler);
+        using TInnerTask = typename SchedulerTraits<typename std::decay<decltype(_taskScheduler)>::type>::TTask;
+
+        bool eventState{false};
+        std::mutex mutexEvent;
+        std::condition_variable event;
+        TInnerTask task = [&] ()
+        {
+            if (calledIds[id] > 0)
+            {
+                std::lock_guard<std::mutex> lck(mutexSetBool);
+                isRecycled = true;
+            }
+
+            ++calledIds[id];
+
+            {
+                std::lock_guard<std::mutex> lck(mutexEvent);
+                eventState = true;
+                event.notify_one();
+            }
+        };
+        scheduleTask(_taskScheduler, task);
+        // need to wait for the internal task_scheduler.
+        {
+            std::unique_lock<std::mutex> lck(mutexEvent);
+            event.wait(lck, [&]{ return eventState; });
+        }
+    };
+
+    try
+    {
+        for (unsigned i = 0; i < 100; ++i)
+        {
+            scheduleTask(scheduler, t);
+        }
+
+        notify(scheduler);
+        seqan::wait(scheduler);
+    }
+    catch (...)
+    {
+        SEQAN_ASSERT_FAIL("Unexpected exception!");
+    }
+
+    auto val = std::accumulate(std::begin(calledIds), std::end(calledIds), 0);
+    SEQAN_ASSERT_EQ(val, 100);
+    SEQAN_ASSERT(isValid(scheduler));
+    SEQAN_ASSERT(isRecycled);
+}
+
+namespace test_align_parallel
+{
+
+struct test_error : public std::exception
+{
+    const char* msg;
+
+    explicit test_error( const char* what_arg ) : std::exception(), msg(what_arg)
+    {}
+
+    explicit test_error( const std::string& what_arg ) : test_error(what_arg.c_str())
+    {}
+
+    virtual const char* what() const noexcept
+    {
+        return msg;
+    }
+};
+
+struct RaiiEvent
+{
+    bool                    eventState{false};
+    std::mutex              mutexEvent{};
+    std::condition_variable event{};
+
+    inline void wait(unsigned const /*id*/)
+    {
+        {
+            std::unique_lock<std::mutex> lck(mutexEvent);
+            event.wait(lck, [&]{ return eventState; });
+        }
+    }
+
+    inline void notify(unsigned const /*id*/)
+    {
+        {
+            std::lock_guard<std::mutex> lck(mutexEvent);
+            eventState = true;
+            event.notify_one();
+        }
+    }
+};
+}
+
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_alignment_scheduler_async_with_exception)
+{
+    using namespace seqan;
+
+    using TTask = SchedulerTraits<WavefrontAlignmentScheduler>::TTask;
+
+    WavefrontAlignmentScheduler scheduler{8,2};
+
+    std::vector<uint16_t>  calledIds{0, 0, 0, 0, 0, 0, 0, 0};
+    bool isRecycled{false};
+    std::mutex mutexSetBool;
+
+    TTask t = [&] (uint16_t const id)
+    {
+        // Now how can we spawn a test to the underlying scheduler.
+        auto& _taskScheduler = taskScheduler(scheduler);
+        using TInnerTask = typename SchedulerTraits<typename std::decay<decltype(_taskScheduler)>::type>::TTask;
+
+        test_align_parallel::RaiiEvent event;
+        TInnerTask task = [&]()
+        {
+            if (calledIds[id] > 0)
+            {
+                std::lock_guard<std::mutex> lck(mutexSetBool);
+                isRecycled = true;
+                if (std::accumulate(std::begin(calledIds), std::end(calledIds), 0) == 50)
+                {
+                    event.notify(id);
+                    throw test_align_parallel::test_error("Test");
+                }
+            }
+            ++calledIds[id];
+            event.notify(id);
+        };
+
+        scheduleTask(_taskScheduler, task);
+        // need to wait for the internal task_scheduler.
+        event.wait(id);
+    };
+
+    try
+    {
+        for (unsigned i = 0; i < 100; ++i)
+        {
+            scheduleTask(scheduler, t);
+        }
+
+        notify(scheduler);
+        seqan::wait(scheduler);
+    }
+    catch (std::runtime_error & e)
+    {
+        std::string msg = e.what();
+        SEQAN_ASSERT_EQ(msg, "Invalid alignment scheduler!");
+    }
+
+    auto exceptVec = getExceptions(scheduler);
+    for (unsigned i = 0; i < exceptVec.size(); ++i)
+    {
+        try
+        {
+            if (exceptVec[i] != nullptr)
+                std::rethrow_exception(exceptVec[i]);
+        }
+        catch (std::runtime_error const & e)
+        {
+            std::string msg = e.what();
+            SEQAN_ASSERT_EQ(msg, "Invalid Task Scheduler");
+        }
+        catch (test_align_parallel::test_error const & e)
+        {
+            std::string msg = e.what();
+            SEQAN_ASSERT_EQ(msg, "Test");
+        }
+        catch (...)
+        {
+            SEQAN_ASSERT_FAIL("Caught unknown exception!");
+        }
+    }
+
+    notify(scheduler);
+    seqan::wait(scheduler);
+    auto val = std::accumulate(std::begin(calledIds), std::end(calledIds), 0);
+    SEQAN_ASSERT_EQ(val, 50);
+    SEQAN_ASSERT_NOT(isValid(scheduler));
+}
diff --git a/include/seqan/parallel/parallel_tags.h b/tests/align_parallel/test_align_wavefront_alignment_thread_local.h
similarity index 51%
copy from include/seqan/parallel/parallel_tags.h
copy to tests/align_parallel/test_align_wavefront_alignment_thread_local.h
index 20d395c..0a2aa8f 100644
--- a/include/seqan/parallel/parallel_tags.h
+++ b/tests/align_parallel/test_align_wavefront_alignment_thread_local.h
@@ -29,58 +29,67 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: David Weese <david.weese at fu-berlin.de>
-// ==========================================================================
-// Tags to select serial/parallel algorithms.
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
-#define SEQAN_PARALLEL_PARALLEL_TAGS_H_
+#include <seqan/align_parallel.h>
 
-namespace seqan {
+namespace test_align_parallel
+{
+struct TestConfig
+{
+    using TCache        = std::vector<int>;
+    using TIntermediate = double;
 
-// ============================================================================
-// Forwards
-// ============================================================================
+    using TLocalHost    = std::tuple<TIntermediate, TCache>;
+};
+}  // namespace test_align_parallel
 
-// ============================================================================
-// Tags, Classes, Enums
-// ============================================================================
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_alignment_thread_local_storage_construt)
+{
+    using namespace seqan;
 
-// ----------------------------------------------------------------------------
-// Tag Parallel
-// ----------------------------------------------------------------------------
+    using TLocalStorage = WavefrontAlignmentThreadLocalStorage<test_align_parallel::TestConfig>;
+    SEQAN_ASSERT(std::is_default_constructible<TLocalStorage>::value);
+    SEQAN_ASSERT(std::is_copy_constructible<TLocalStorage>::value);
+    SEQAN_ASSERT(std::is_move_constructible<TLocalStorage>::value);
+    SEQAN_ASSERT(std::is_copy_assignable<TLocalStorage>::value);
+    SEQAN_ASSERT(std::is_move_assignable<TLocalStorage>::value);
 
-/*!
- * @defgroup ParallelismTags Parallelism Tags
- * @brief Tags for enabling/disabling parallelism.
- *
- * @tag ParallelismTags#Parallel
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the parallel implementation of an algorithm.
- *
- * @tag ParallelismTags#Serial
- * @headerfile <seqan/parallel.h>
- * @brief Tag to select the serial implementation of an algorithm.
- */
+    {
+        TLocalStorage store;
+        SEQAN_ASSERT_EQ(store._multiAlignmentThreadLocal.size(), 1u);
+    }
 
-struct Parallel_;
-typedef Tag<Parallel_> Parallel;
+    {
+        TLocalStorage store{3};
+        SEQAN_ASSERT_EQ(store._multiAlignmentThreadLocal.size(), 3u);
+    }
+}
 
-// ============================================================================
-// Metafunctions
-// ============================================================================
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_alignment_thread_local_storage_intermediate)
+{
+    using namespace seqan;
 
-// ----------------------------------------------------------------------------
-// Metafunction DefaultParallelSpec
-// ----------------------------------------------------------------------------
+    using TLocalStorage = WavefrontAlignmentThreadLocalStorage<test_align_parallel::TestConfig>;
+    {
+        TLocalStorage store{3};
+        auto & interim = intermediate(store, 1);
+        interim = 2.3;
+        SEQAN_ASSERT_EQ(intermediate(store, 1), 2.3);
+    }
+}
 
-template <typename TObject>
-struct DefaultParallelSpec
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_alignment_thread_local_storage_cache)
 {
-    typedef Parallel Type;
-};
-
-}  // namespace seqan
+    using namespace seqan;
 
-#endif  // #ifndef SEQAN_PARALLEL_PARALLEL_TAGS_H_
+    using TLocalStorage = WavefrontAlignmentThreadLocalStorage<test_align_parallel::TestConfig>;
+    {
+        TLocalStorage store{3};
+        auto & local = cache(store, 1);
+        local.resize(5, 10);
+        SEQAN_ASSERT_EQ(cache(store, 1).size(), 5u);
+        SEQAN_ASSERT_EQ(cache(store, 1)[0], 10);
+    }
+}
diff --git a/tests/align_parallel/test_align_wavefront_intermediate_dp_result.h b/tests/align_parallel/test_align_wavefront_intermediate_dp_result.h
new file mode 100644
index 0000000..cf1bd91
--- /dev/null
+++ b/tests/align_parallel/test_align_wavefront_intermediate_dp_result.h
@@ -0,0 +1,121 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#include <seqan/align_parallel.h>
+
+namespace test_align_parallel
+{
+struct IntermediateTraits_
+{
+    using TScoreValue   = int;
+    using THostPosition = size_t;
+};
+
+}  // namespace test_align_parallel
+
+SEQAN_DEFINE_TEST(test_align_parallel_intermediate_dp_result_construct)
+{
+    using namespace seqan;
+
+    using TIntermediate = WavefrontAlignmentResult<test_align_parallel::IntermediateTraits_>;
+
+    SEQAN_ASSERT(std::is_default_constructible<TIntermediate>::value);
+    SEQAN_ASSERT(std::is_copy_constructible<TIntermediate>::value);
+    SEQAN_ASSERT(std::is_move_constructible<TIntermediate>::value);
+    SEQAN_ASSERT(std::is_copy_assignable<TIntermediate>::value);
+    SEQAN_ASSERT(std::is_move_assignable<TIntermediate>::value);
+
+    {
+        TIntermediate interim;
+        SEQAN_ASSERT_EQ(interim._maxState.first, std::numeric_limits<int>::min());
+        SEQAN_ASSERT_EQ(interim._maxState.second, 0u);
+        SEQAN_ASSERT_EQ(interim._tileCol, 0u);
+        SEQAN_ASSERT_EQ(interim._tileRow, 0u);
+    }
+
+    {
+        TIntermediate interim{{10, 3u}};
+        SEQAN_ASSERT_EQ(interim._maxState.first, 10);
+        SEQAN_ASSERT_EQ(interim._maxState.second, 3u);
+        SEQAN_ASSERT_EQ(interim._tileCol, 0u);
+        SEQAN_ASSERT_EQ(interim._tileRow, 0u);
+    }
+
+    {
+        TIntermediate interim{{10, 3u}, 2u, 4u};
+        SEQAN_ASSERT_EQ(interim._maxState.first, 10);
+        SEQAN_ASSERT_EQ(interim._maxState.second, 3u);
+        SEQAN_ASSERT_EQ(interim._tileCol, 2u);
+        SEQAN_ASSERT_EQ(interim._tileRow, 4u);
+    }
+}
+
+SEQAN_DEFINE_TEST(test_align_parallel_intermediate_dp_result_update_max)
+{
+    using namespace seqan;
+
+    using TIntermediate = WavefrontAlignmentResult<test_align_parallel::IntermediateTraits_>;
+    using TState = typename TIntermediate::TState;
+
+    TIntermediate interim{{10, 3u}, 2, 4};
+    updateMax(interim, TState{9, 7u}, 3, 5);
+    SEQAN_ASSERT_EQ(interim._maxState.first, 10);
+    SEQAN_ASSERT_EQ(interim._maxState.second, 3u);
+    SEQAN_ASSERT_EQ(interim._tileCol, 2u);
+    SEQAN_ASSERT_EQ(interim._tileRow, 4u);
+
+    updateMax(interim, TState{11, 7u}, 3, 5);
+    SEQAN_ASSERT_EQ(interim._maxState.first, 11);
+    SEQAN_ASSERT_EQ(interim._maxState.second, 7u);
+    SEQAN_ASSERT_EQ(interim._tileCol, 3u);
+    SEQAN_ASSERT_EQ(interim._tileRow, 5u);
+
+}
+
+SEQAN_DEFINE_TEST(test_align_parallel_intermediate_dp_result_clear)
+{
+    using namespace seqan;
+
+    using TIntermediate = WavefrontAlignmentResult<test_align_parallel::IntermediateTraits_>;
+
+    {
+        TIntermediate interim{{10, 3u}, 2, 4};
+        clear(interim);
+
+        SEQAN_ASSERT_EQ(interim._maxState.first, std::numeric_limits<int>::min());
+        SEQAN_ASSERT_EQ(interim._maxState.second, 0u);
+        SEQAN_ASSERT_EQ(interim._tileCol, 0u);
+        SEQAN_ASSERT_EQ(interim._tileRow, 0u);
+    }
+}
diff --git a/tests/multiple_translation_units/test_multiple_translation_units.cpp b/tests/align_parallel/test_align_wavefront_task_scheduler.h
similarity index 53%
copy from tests/multiple_translation_units/test_multiple_translation_units.cpp
copy to tests/align_parallel/test_align_wavefront_task_scheduler.h
index 650820e..81b8112 100644
--- a/tests/multiple_translation_units/test_multiple_translation_units.cpp
+++ b/tests/align_parallel/test_align_wavefront_task_scheduler.h
@@ -29,56 +29,71 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: Jochen Singer <jochen.singer at fu-berlin.de>
+// Author: Rene Rahn <rene.rahn at fu-berlin.de>
 // ==========================================================================
 
-#include <seqan/align.h>
-#include <seqan/align_extend.h>
-#include <seqan/align_profile.h>
-#include <seqan/align_split.h>
-#include <seqan/alignment_free.h>
-#include <seqan/arg_parse.h>
-#include <seqan/bam_io.h>
-#include <seqan/basic.h>
-#include <seqan/bed_io.h>
-#include <seqan/consensus.h>
-#include <seqan/file.h>
-#include <seqan/find.h>
-#include <seqan/gff_io.h>
-#include <seqan/graph_algorithms.h>
-#include <seqan/graph_align.h>
-#include <seqan/graph_msa.h>
-#include <seqan/graph_types.h>
-#include <seqan/index.h>
-#include <seqan/journaled_set.h>
-#include <seqan/map.h>
-#include <seqan/math.h>
-#include <seqan/modifier.h>
-#include <seqan/parallel.h>
-#include <seqan/parse_lm.h>
-#include <seqan/pipe.h>
-#include <seqan/platform.h>
-#include <seqan/random.h>
-#include <seqan/realign.h>
-#include <seqan/reduced_aminoacid.h>
-#include <seqan/roi_io.h>
-#include <seqan/score.h>
-#include <seqan/seeds.h>
-#include <seqan/seq_io.h>
-#include <seqan/sequence.h>
-#include <seqan/sequence_journaled.h>
-#include <seqan/simple_intervals_io.h>
-#include <seqan/statistics.h>
-#include <seqan/store.h>
-#include <seqan/stream.h>
-#include <seqan/system.h>
-#include <seqan/translation.h>
-#include <seqan/ucsc_io.h>
-#include <seqan/vcf_io.h>
-#include <seqan/version.h>
+#include <seqan/align_parallel.h>
 
-// This test simply checks whether all functions are inline or templates.
-SEQAN_BEGIN_TESTSUITE(test_multiple_translation_units)
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_task_scheduler_construct)
 {
+    using namespace seqan;
+
+    // We need to be able to construct a thread pool.
+    SEQAN_ASSERT(!std::is_default_constructible<WavefrontTaskScheduler>::value);
+    SEQAN_ASSERT(!std::is_copy_constructible<WavefrontTaskScheduler>::value);
+    SEQAN_ASSERT(!std::is_move_constructible<WavefrontTaskScheduler>::value);
+    SEQAN_ASSERT(!std::is_copy_assignable<WavefrontTaskScheduler>::value);
+    SEQAN_ASSERT(!std::is_move_assignable<WavefrontTaskScheduler>::value);
+
+    try
+    {
+        WavefrontTaskScheduler scheduler(4);
+        waitForWriters(scheduler);
+    }
+    catch(...)
+    {
+        SEQAN_ASSERT_FAIL("Error during construction of scheduler!");
+    }
+}
+
+SEQAN_DEFINE_TEST(test_align_parallel_wavefront_task_scheduler_async)
+{
+    using namespace seqan;
+
+    using TTask = SchedulerTraits<WavefrontTaskScheduler>::TTask;
+
+    WavefrontTaskScheduler scheduler{2, 1};
+
+    bool t1Executed{false};
+    TTask t1 = [&]()
+    {
+        t1Executed = true;
+    };
+    bool t2Executed{false};
+    TTask t2 = [&]()
+    {
+        t2Executed = true;
+    };
+
+    // Register writer.
+    lockWriting(scheduler);
+
+    // Schedule jobs for async execution.
+    scheduleTask(scheduler, t1);
+    scheduleTask(scheduler, t2);
+
+    SEQAN_ASSERT_NOT(t1Executed);
+    SEQAN_ASSERT_NOT(t2Executed);
+
+    // Trigger execution.
+    waitForWriters(scheduler);
+
+    // Unregister writer.
+    unlockWriting(scheduler);
+
+    // Wait until schduler is done with all jobs.
+    seqan::wait(scheduler);
+
+    SEQAN_ASSERT(t1Executed);
+    SEQAN_ASSERT(t2Executed);
 }
-SEQAN_END_TESTSUITE
diff --git a/tests/arg_parse/test_arg_parse.cpp b/tests/arg_parse/test_arg_parse.cpp
index aec4bcb..100ec59 100644
--- a/tests/arg_parse/test_arg_parse.cpp
+++ b/tests/arg_parse/test_arg_parse.cpp
@@ -144,6 +144,7 @@ SEQAN_BEGIN_TESTSUITE(test_arg_parse)
     SEQAN_CALL_TEST(test_argument_invalid_cast);
     SEQAN_CALL_TEST(test_argument_min_max_boundaries);
     SEQAN_CALL_TEST(test_argument_valid_values);
+    SEQAN_CALL_TEST(test_argument_valid_values_directories);
 
     SEQAN_CALL_TEST(test_argument_parser);
     SEQAN_CALL_TEST(test_parse_non_const_cstring);
diff --git a/tests/arg_parse/test_arg_parse_argument.h b/tests/arg_parse/test_arg_parse_argument.h
index 675e403..b46fb84 100644
--- a/tests/arg_parse/test_arg_parse_argument.h
+++ b/tests/arg_parse/test_arg_parse_argument.h
@@ -223,4 +223,32 @@ SEQAN_DEFINE_TEST(test_argument_valid_values)
                          "the given path 'not-a-validfile.qxt' does not have one of the valid file extensions [*.txt, *.fasta]; the file extension was overridden to be '.fa'");
 }
 
+SEQAN_DEFINE_TEST(test_argument_valid_values_directories)
+{
+    ArgParseArgument dirarg(ArgParseArgument::INPUT_DIRECTORY);
+    setValidValues(dirarg, ".dir1 .dir2");
+
+    _assignArgumentValue(dirarg, "directory.dir1");
+    SEQAN_ASSERT_EQ(value(dirarg.value, 0), "directory.dir1");
+
+    // Test getFileExtension() function.
+    SEQAN_ASSERT_EQ(getFileExtension(dirarg), ".dir1");
+
+    // different case should also work
+    _assignArgumentValue(dirarg, "directory.DIR1");
+    SEQAN_ASSERT_EQ(value(dirarg.value, 0), "directory.DIR1");
+
+    // also accept a trailing '/'
+    _assignArgumentValue(dirarg, "directory.dir2/");
+    SEQAN_ASSERT_EQ(value(dirarg.value, 0), "directory.dir2/");
+
+    // Test getFileExtension() function.
+    SEQAN_ASSERT_EQ(getFileExtension(dirarg), ".dir2");
+
+    // different case should also work
+    _assignArgumentValue(dirarg, "directory.DIR2/");
+    SEQAN_ASSERT_EQ(value(dirarg.value, 0), "directory.DIR2/");
+
+}
+
 #endif // SEQAN_TESTS_ARG_PARSE_TEST_ARG_PARSE_ARGUMENT_H_
diff --git a/tests/basic/test_basic_aggregate.h b/tests/basic/test_basic_aggregate.h
index b1090a5..4e43ddc 100644
--- a/tests/basic/test_basic_aggregate.h
+++ b/tests/basic/test_basic_aggregate.h
@@ -479,7 +479,10 @@ SEQAN_DEFINE_TEST(test_basic_aggregates_pair_packed_constructors)
 
     // Default constructor.
     {
-        TPair p;
+        TPair p{};
+
+        SEQAN_ASSERT_EQ(p.i1, 0);
+        SEQAN_ASSERT_EQ(p.i2, 0u);
     }
 
     // Normal Constructor Pair(i1, i2).
diff --git a/tests/index/CMakeLists.txt b/tests/index/CMakeLists.txt
index eed4089..ad1c9e3 100644
--- a/tests/index/CMakeLists.txt
+++ b/tests/index/CMakeLists.txt
@@ -141,6 +141,11 @@ add_executable (test_find_backtracking
                 test_find_base.h)
 target_link_libraries (test_find_backtracking ${SEQAN_LIBRARIES})
 
+add_executable (test_find2_index_approx
+                test_find2_index_approx.cpp
+                test_find2_index_approx.h)
+target_link_libraries (test_find2_index_approx ${SEQAN_LIBRARIES})
+
 add_executable (test_index_repeats
                test_index_repeats.cpp
                test_index_repeats.h)
@@ -180,4 +185,3 @@ add_test (NAME test_test_index_view COMMAND $<TARGET_FILE:test_index_view>)
 add_test (NAME test_test_index_finder COMMAND $<TARGET_FILE:test_index_finder>)
 add_test (NAME test_test_find_backtracking COMMAND $<TARGET_FILE:test_find_backtracking>)
 add_test (NAME test_test_index_repeats COMMAND $<TARGET_FILE:test_index_repeats>)
-
diff --git a/tests/align/test_align_simd.cpp b/tests/index/test_find2_index_approx.cpp
similarity index 77%
rename from tests/align/test_align_simd.cpp
rename to tests/index/test_find2_index_approx.cpp
index 405b6b6..2b15442 100644
--- a/tests/align/test_align_simd.cpp
+++ b/tests/index/test_find2_index_approx.cpp
@@ -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
@@ -12,14 +12,14 @@
 //     * 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
+//     * Neither the name of NVIDIA Corporation 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
+// ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION 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
@@ -29,15 +29,18 @@
 // DAMAGE.
 //
 // ==========================================================================
-// Author: René Rahn <rene.rahn at fu-berlin.de>
+// Author: Christopher Pockrandt <github at cpockrandt.de>
 // ==========================================================================
 
 #include <seqan/basic.h>
-#include <seqan/stream.h>
 
-#include "test_align_simd.h"
+#include "test_find2_index_approx.h"
 
-int main(int argc, char const ** argv) {
-    seqan::TestSystem::init(argc, argv);
-    return seqan::TestSystem::runAll();
+SEQAN_BEGIN_TESTSUITE(test_find_index_approx)
+{
+    // Call tests.
+    SEQAN_CALL_TEST(test_find2_index_approx_hamming);
+    SEQAN_CALL_TEST(test_find2_index_approx_edit);
+    SEQAN_CALL_TEST(test_find2_index_approx_small_test);
 }
+SEQAN_END_TESTSUITE
diff --git a/tests/index/test_find2_index_approx.h b/tests/index/test_find2_index_approx.h
new file mode 100644
index 0000000..dddb976
--- /dev/null
+++ b/tests/index/test_find2_index_approx.h
@@ -0,0 +1,489 @@
+// ==========================================================================
+//                 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 NVIDIA Corporation 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 NVIDIA CORPORATION 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: Christopher Pockrandt <github at cpockrandt.de>
+// ==========================================================================
+
+#ifndef TESTS_FIND2_INDEX_APPROX_H_
+#define TESTS_FIND2_INDEX_APPROX_H_
+
+#include <mutex>
+#include <ctime>
+
+#include <seqan/index.h>
+
+#include "test_index_helpers.h"
+
+using namespace seqan;
+
+// ============================================================================
+// Functions
+// ============================================================================
+
+template <typename TChar, typename TConfig>
+void generateText(String<TChar, TConfig> & text, unsigned const length)
+{
+    unsigned alphabetSize = ValueSize<TChar>::VALUE;
+    unsigned minChar = MinValue<TChar>::VALUE;
+
+    resize(text, length);
+
+    for (unsigned i = 0; i < length; ++i)
+    {
+        text[i] = std::rand() % alphabetSize - minChar;
+    }
+}
+
+template< typename TContainer>
+inline void printVector(const TContainer & c, std::ostream & stream)
+{
+    using T = std::decay_t<decltype(c[0])>;
+    stream << "[";
+    for (uint8_t i = 0; i < c.size(); ++i)
+    {
+        stream << (std::is_same<T, uint8_t>::value ? (unsigned) c[i] : c[i])
+               << ((i < c.size() - 1) ? ", " : "");
+    }
+    stream << "]" << std::endl;
+}
+
+template <size_t nbrBlocks>
+inline void printSearch(OptimalSearch<nbrBlocks> const & s, std::ostream & stream)
+{
+    stream << "SearchScheme (Pi): ";
+    printVector(s.pi, stream);
+    stream << "SearchScheme (L): ";
+    printVector(s.l, stream);
+    stream << "SearchScheme (U): ";
+    printVector(s.u, stream);
+    stream << "SearchScheme (BL): ";
+    printVector(s.blocklength, stream);
+}
+
+inline void _getErrorDistributions(std::vector<std::vector<uint8_t> > & res,
+                                   std::vector<uint8_t> l,
+                                   std::vector<uint8_t> u,
+                                   uint8_t const e)
+{
+    if (l.size() == 0)
+    {
+        std::vector<uint8_t> emptyVector;
+        res.push_back(emptyVector);
+        return;
+    }
+
+    uint8_t l1 = l[0];
+    uint8_t u1 = u[0];
+    l.erase(l.begin());
+    u.erase(u.begin());
+
+    for (uint8_t i = std::max(e, l1); i <= u1; ++i)
+    {
+        std::vector<std::vector<uint8_t> > _res;
+        _getErrorDistributions(_res, l, u, i);
+        for (auto & _resElem : _res)
+        {
+            _resElem.insert(_resElem.begin(), i - e);
+            res.push_back(_resElem);
+        }
+    }
+}
+
+// Compute all possible error distributions given a search.
+// The result is ordered as the search (s.pi)
+template <size_t nbrBlocks>
+inline void getErrorDistributions(std::vector<std::vector<uint8_t> > & res,
+                                  OptimalSearch<nbrBlocks> const & s)
+{
+    std::vector<uint8_t> l(s.l.begin(), s.l.end());
+    std::vector<uint8_t> u(s.u.begin(), s.u.end());
+    _getErrorDistributions(res, l, u, 0u);
+}
+
+// Reorder blocks s.t. they are in a sequential order (from left to right)
+template <size_t nbrBlocks, typename T>
+inline void orderVector(OptimalSearch<nbrBlocks> const & s, std::vector<T> & v)
+{
+    std::vector<T> v_tmp = v;
+    for (uint8_t i = 0; i < s.pi.size(); ++i)
+    {
+        uint8_t index = s.pi[i] - 1;
+        v[index] = v_tmp[i];
+    }
+}
+
+// Reorder blocks s.t. they are in a sequential order (from left to right)
+// Blocklength is stored as absolute values instead of cumulative values.
+template <size_t nbrBlocks>
+inline void getOrderedSearch(OptimalSearch<nbrBlocks> const & s, OptimalSearch<nbrBlocks> & os)
+{
+    for (uint8_t i = 0; i < s.pi.size(); ++i)
+    {
+        uint8_t index = s.pi[i] - 1;
+        os.pi[index] = s.pi[i];
+        os.l[index] = s.l[i];
+        os.u[index] = s.u[i];
+        os.blocklength[index] = s.blocklength[i] - ((i > 0) ? s.blocklength[i - 1] : 0);
+    }
+}
+
+// Trivial backtracking that finds *all* matches with given distance.
+template <typename TDelegate, typename TText, typename TIndex,
+          typename TIndexSpec, typename TText2, typename TNeedleIter>
+inline void trivialSearch(TDelegate && delegate,
+                          Iter<Index<TText, TIndex>, VSTree<TopDown<TIndexSpec> > > it,
+                          TText2 const & needle,
+                          TNeedleIter const needleIt,
+                          uint8_t const errorsLeft,
+                          bool const indels)
+{
+    if (errorsLeft == 0)
+    {
+        if (goDown(it, suffix(needle, position(needleIt, needle)), Rev()))
+            delegate(it);
+        return;
+    }
+
+    if (atEnd(needleIt, needle))
+    {
+        delegate(it);
+        if (!(indels && errorsLeft > 0))
+            return;
+    }
+
+    // Insertion
+    if (indels && !atEnd(needleIt, needle))
+        trivialSearch(delegate, it, needle, needleIt + 1, errorsLeft - 1, indels);
+
+    if (goDown(it, Rev()))
+    {
+        do
+        {
+            // Match / Mismatch
+            if (!atEnd(needleIt, needle))
+            {
+                auto delta = !ordEqual(parentEdgeLabel(it, Rev()), value(needleIt));
+                trivialSearch(delegate, it, needle, needleIt + 1, errorsLeft - delta, indels);
+            }
+
+            // Deletion
+            if (indels)
+                trivialSearch(delegate, it, needle, needleIt, errorsLeft - 1, indels);
+
+        } while (goRight(it, Rev()));
+    }
+}
+
+// Compute random blocklengths (order: left to right)
+template <size_t nbrBlocks, size_t N>
+inline void setRandomBlockLength(std::array<OptimalSearch<nbrBlocks>, N> & ss, uint32_t needleLength)
+{
+    std::vector<uint32_t> blocklength(ss[0].pi.size());
+
+    // Set minimum length for each block considerung all searches.
+    uint8_t maxErrors = 0;
+    for (auto const & s : ss)
+        maxErrors = std::max(maxErrors, s.u.back());
+    // NOTE(cpockrandt): this enforces to be the needles much longer than necessary!
+    for (uint8_t i = 0; i < blocklength.size(); ++i)
+        blocklength[i] = maxErrors;
+    needleLength -= maxErrors * blocklength.size();
+
+    // Randomly distribute the rest on all blocks
+    while (needleLength > 0)
+    {
+        ++blocklength[std::rand() % blocklength.size()];
+        --needleLength;
+    }
+
+    _optimalSearchSchemeSetBlockLength(ss, blocklength);
+    _optimalSearchSchemeInit(ss);
+}
+
+template <typename TText, typename TIndex, typename TIndexSpec, size_t nbrBlocks, typename TDistanceTag>
+inline void testOptimalSearch(Iter<Index<TText, BidirectionalIndex<TIndex> >, VSTree<TopDown<TIndexSpec> > > it,
+                              OptimalSearch<nbrBlocks> const & s,
+                              OptimalSearch<nbrBlocks> const & os,
+                              unsigned const needleLength,
+                              std::vector<uint8_t> const & errorDistribution,
+                              time_t const seed,
+                              TDistanceTag const & /**/)
+{
+    typedef typename Value<TText>::Type TChar;
+    typedef Iter<Index<TText, BidirectionalIndex<TIndex> >, VSTree<TopDown<TIndexSpec> > >  TIt;
+
+    TText & text = indexText(container(it.fwdIter));
+
+    unsigned pos = std::rand() % (length(text) - needleLength + 1);
+    TText origNeedle(infix(text, pos, pos + needleLength));
+
+    // Modify needle s.t. it has errors matching errorDistribution.
+    TText needle(origNeedle);
+    uint32_t cumulativeBlocklength = 0;
+    for (uint8_t block = 0; block < s.pi.size(); ++block)
+    {
+        uint32_t blocklength = os.blocklength[block];
+        if (errorDistribution[block] > blocklength)
+        {
+            std::stringstream stream;
+            stream << "Error in block " << (unsigned) block << "(+ 1): "
+                   << (unsigned) errorDistribution[block]
+                   << " errors cannot fit into a block of length "
+                   << (unsigned) blocklength << "." << std::endl;
+            stream << "Error Distribution: ";
+            printVector(errorDistribution, stream);
+            printSearch(s, stream);
+            printSearch(os, stream);
+            SEQAN_ASSERT_FAIL(toCString(stream.str()));
+        }
+
+        // choose random positions in needle that will be a mismatch/indel
+        // repeat until all error positions are unique
+        std::vector<uint8_t> errorPositions(errorDistribution[block]);
+        do
+        {
+            clear(errorPositions);
+            for (uint8_t error = 0; error < errorDistribution[block]; ++error)
+                errorPositions.push_back(std::rand() % blocklength);
+            sort(errorPositions.begin(), errorPositions.end());
+        } while (adjacent_find(errorPositions.begin(), errorPositions.end()) != errorPositions.end());
+
+        // construct needle with chosen error positions
+        for (unsigned error = 0; error < errorPositions.size(); ++error)
+        {
+            unsigned pos = errorPositions[error] + cumulativeBlocklength;
+            TChar newChar;
+            do
+            {
+                newChar = TChar(std::rand() % ValueSize<TChar>::VALUE);
+            } while(needle[pos] == newChar);
+            needle[pos] = newChar;
+        }
+        cumulativeBlocklength += blocklength;
+    }
+
+    std::vector<unsigned> hits, expectedHitsSS, expectedHitsTrivial;
+    auto delegate = [&hits](TIt const & it, TText const & /*needle*/, uint8_t /*errors*/)
+    {
+        for (unsigned i = 0; i < length(getOccurrences(it)); ++i)
+            hits.push_back(getOccurrences(it)[i]);
+    };
+    auto delegateTrivial = [&hits](TIt const & it)
+    {
+        for (unsigned i = 0; i < length(getOccurrences(it)); ++i)
+            hits.push_back(getOccurrences(it)[i]);
+    };
+
+    // Find all hits using search schemes.
+    _optimalSearchScheme(delegate, it, needle, s, TDistanceTag());
+    for (unsigned hit : hits)
+        if (infix(text, hit, hit + needleLength) == origNeedle)
+            expectedHitsSS.push_back(hit);
+
+    // Find all hits using trivial backtracking.
+    clear(hits);
+    uint8_t maxErrors = s.u.back();
+    trivialSearch(delegateTrivial, it, needle, begin(needle, Standard()), maxErrors, std::is_same<TDistanceTag, EditDistance>::value);
+    for (unsigned hit : hits)
+    {
+        // filter only correct error distributions
+        if (origNeedle == infix(text, hit, hit + needleLength))
+        {
+            bool distributionOkay = true;
+            unsigned leftRange = 0, rightRange = 0;
+            for (unsigned block = 0; block < s.pi.size(); ++block)
+            {
+                rightRange += os.blocklength[block];
+
+                uint8_t errors = 0;
+                for (unsigned i = leftRange; i < rightRange; ++i)
+                    if (hit + i >= length(text))
+                        ++errors;
+                    else
+                        errors += !ordEqual(needle[i], text[hit + i]);
+                if (errors != errorDistribution[block])
+                    distributionOkay = false;
+                leftRange += os.blocklength[block];
+            }
+            if (distributionOkay || std::is_same<TDistanceTag, EditDistance>::value)
+                expectedHitsTrivial.push_back(hit);
+        }
+    }
+
+    // eliminate duplicates
+    sort(expectedHitsSS.begin(), expectedHitsSS.end());
+    sort(expectedHitsTrivial.begin(), expectedHitsTrivial.end());
+    expectedHitsSS.erase(unique(expectedHitsSS.begin(), expectedHitsSS.end()), expectedHitsSS.end());
+    expectedHitsTrivial.erase(unique(expectedHitsTrivial.begin(), expectedHitsTrivial.end()), expectedHitsTrivial.end());
+
+    if (expectedHitsSS != expectedHitsTrivial)
+    {
+        std::stringstream stream;
+        stream << "Seed: " << seed << std::endl
+               << "Text: " << text << std::endl
+               << "ErrorDistribution: ";
+        printVector(errorDistribution, stream);
+        stream << "Original: " << origNeedle << std::endl
+               << "Modified: " << needle << std::endl
+               << "ExpectedHitsSS: ";
+        printVector(expectedHitsSS, stream);
+        stream << "ExpectedHitsTrivial: ";
+        printVector(expectedHitsTrivial, stream);
+        printSearch(s, stream);
+        SEQAN_ASSERT_FAIL(toCString(stream.str()));
+    }
+}
+
+template <size_t nbrBlocks, size_t N, typename TDistanceTag>
+inline void testOptimalSearchScheme(std::array<OptimalSearch<nbrBlocks>, N> ss, TDistanceTag const & /**/)
+{
+    typedef DnaString TText;
+    typedef FastFMIndexConfig<void, uint32_t, 2, 1> TMyFastConfig;
+    typedef Index<TText, BidirectionalIndex<FMIndex<void, TMyFastConfig> > > TIndex;
+    typedef Iter<TIndex, VSTree<TopDown<> > > TIter;
+
+    time_t seed = std::time(nullptr);
+    std::srand(seed);
+
+    TText text;
+    std::array<OptimalSearch<nbrBlocks>, N> os;
+    std::vector<std::vector<std::vector<uint8_t> > > errorDistributions(ss.size());
+
+    // Calculate all error distributions and sort each of them (from left to right).
+    uint8_t errors = 0;
+    for (uint8_t schemeId = 0; schemeId < ss.size(); ++schemeId)
+    {
+        os[schemeId] = ss[schemeId];
+        getErrorDistributions(errorDistributions[schemeId], ss[schemeId]);
+        for (std::vector<uint8_t> & resElem : errorDistributions[schemeId])
+            orderVector(ss[schemeId], resElem);
+        errors = std::max(errors, ss[schemeId].u.back());
+    }
+
+    for (uint32_t textLength = 10; textLength < 10000; textLength *= 10)
+    {
+        generateText(text, textLength);
+        TIndex index(text);
+        TIter it(index);
+        for (uint16_t needleLength = std::max(static_cast<size_t>(5), ss[0].pi.size() * errors); needleLength < std::min(16u, textLength); ++needleLength)
+        {
+            setRandomBlockLength(ss, needleLength);
+
+            for (uint8_t schemeId = 0; schemeId < ss.size(); ++schemeId)
+                getOrderedSearch(ss[schemeId], os[schemeId]);
+
+            for (uint8_t schemeId = 0; schemeId < ss.size(); ++schemeId)
+                for (auto & errorDistribution : errorDistributions[schemeId])
+                    testOptimalSearch(it, ss[schemeId], os[schemeId], needleLength, errorDistribution, seed, TDistanceTag());
+        }
+    }
+}
+
+// ============================================================================
+// Tests
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// Test test_find2_index_approx_hamming
+// ----------------------------------------------------------------------------
+
+SEQAN_DEFINE_TEST(test_find2_index_approx_hamming)
+{
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 0>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 1>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 2>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 3>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 4>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<1, 1>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<1, 2>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<1, 3>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<1, 4>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<2, 2>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<2, 3>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<2, 4>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<3, 3>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<3, 4>::VALUE, HammingDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<4, 4>::VALUE, HammingDistance());
+}
+
+// ----------------------------------------------------------------------------
+// Test test_find2_index_approx_edit
+// ----------------------------------------------------------------------------
+
+SEQAN_DEFINE_TEST(test_find2_index_approx_edit)
+{
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 0>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 1>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 2>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 3>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<0, 4>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<1, 1>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<1, 2>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<1, 3>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<1, 4>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<2, 2>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<2, 3>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<2, 4>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<3, 3>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<3, 4>::VALUE, EditDistance());
+    testOptimalSearchScheme(OptimalSearchSchemes<4, 4>::VALUE, EditDistance());
+}
+
+SEQAN_DEFINE_TEST(test_find2_index_approx_small_test)
+{
+    DnaString genome(
+        "GAGAGGCCACTCGCAGGATTAAGTCAATAAGTTAATGGCGTCGGCTTCCTGGTATGTAGTACGACGCCCACAGTGACCTCATCGGTGCATTTCCTCATCGTAG"
+        "GCGGAACGGTAGACACAAGGCATGATGTCAAATCGCGACTCCAATCCCAAGGTCGCAAGCCTATATAGGAACCCGCTTATGCCCTCTAATCCCGGACAGACCC"
+        "CAAATATGGCATAGCTGGTTGGGGGTACCTACTAGGCACAGCCGGAAGCA");
+    StringSet<DnaString> needles;
+    appendValue(needles, "GGGGTTAT");
+    appendValue(needles, "CTAGCTAA");
+
+    std::set<unsigned> hits, expectedHits {186, 226, 227, 234};
+
+    std::mutex mtx;
+    auto delegate = [&hits, &mtx](auto & iter, DnaString const & /*pattern*/, uint8_t /*errors*/)
+    {
+        std::lock_guard<std::mutex> lck(mtx);
+        for (auto occ : getOccurrences(iter))
+            hits.insert(occ);
+    };
+    Index<DnaString, BidirectionalIndex<FMIndex<> > > index(genome);
+
+    find<1, 2>(delegate, index, needles, EditDistance(), Serial());
+    SEQAN_ASSERT(hits == expectedHits);
+
+    hits.clear();
+    find<1, 2>(delegate, index, needles, EditDistance(), Parallel());
+    SEQAN_ASSERT(hits == expectedHits);
+}
+
+#endif  // TESTS_FIND2_INDEX_APPROX_H_
diff --git a/tests/index/test_index_bifm.cpp b/tests/index/test_index_bifm.cpp
index 742835c..c28213c 100644
--- a/tests/index/test_index_bifm.cpp
+++ b/tests/index/test_index_bifm.cpp
@@ -32,8 +32,6 @@
 // Author: Christopher Pockrandt <christopher.pockrandt at fu-berlin.de>
 // ==========================================================================
 
-#include <seqan/basic.h>
-#include <seqan/reduced_aminoacid.h>
 #include <seqan/index.h>
 #include <ctime>
 
@@ -61,22 +59,14 @@ struct FMIndexWTConfig
     static const unsigned SAMPLING =                                        10;
 };
 
-typedef String<SimpleType<unsigned char, ReducedAminoAcid_<Murphy10> > > Murphy10String;
-
 typedef
     TagList<Index<String<bool>,   BidirectionalIndex<FMIndex<void, FMIndexConfigLevelsPrefix<> > > >,
     TagList<Index<DnaString,      BidirectionalIndex<FMIndex<void, FMIndexConfigLevelsPrefix<> > > >,
     TagList<Index<Dna5String,     BidirectionalIndex<FMIndex<void, FMIndexConfigLevelsPrefix<> > > >,
-    TagList<Index<Murphy10String, BidirectionalIndex<FMIndex<void, FMIndexConfigLevelsPrefix<> > > >,
-    TagList<Index<Peptide,        BidirectionalIndex<FMIndex<void, FMIndexConfigLevelsPrefix<> > > >,
-    TagList<Index<CharString,     BidirectionalIndex<FMIndex<void, FMIndexConfigLevelsPrefix<> > > >,
     TagList<Index<String<bool>,   BidirectionalIndex<FMIndex<void, FMIndexWTConfig<> > > >,
     TagList<Index<DnaString,      BidirectionalIndex<FMIndex<void, FMIndexWTConfig<> > > >,
-    TagList<Index<Dna5String,     BidirectionalIndex<FMIndex<void, FMIndexWTConfig<> > > >,
-    TagList<Index<Murphy10String, BidirectionalIndex<FMIndex<void, FMIndexWTConfig<> > > >,
-    TagList<Index<Peptide,        BidirectionalIndex<FMIndex<void, FMIndexWTConfig<> > > >,
-    TagList<Index<CharString,     BidirectionalIndex<FMIndex<void, FMIndexWTConfig<> > > >
-    > > > > > > > > > > > >
+    TagList<Index<Dna5String,     BidirectionalIndex<FMIndex<void, FMIndexWTConfig<> > > >
+    > > > > > >
     FMIndices;
 
 // ==========================================================================
diff --git a/tests/modifier/test_modifier.cpp b/tests/modifier/test_modifier.cpp
index 9b139a9..ec6fc83 100644
--- a/tests/modifier/test_modifier.cpp
+++ b/tests/modifier/test_modifier.cpp
@@ -42,7 +42,7 @@
 #include "test_modifier_string_padding.h"
 
 
-SEQAN_BEGIN_TESTSUITE(test_modifier) 
+SEQAN_BEGIN_TESTSUITE(test_modifier)
 {
     // Test the modifier shortcuts.
     SEQAN_CALL_TEST(test_modifer_shortcuts_dna_string_reverse);
@@ -130,5 +130,6 @@ SEQAN_BEGIN_TESTSUITE(test_modifier)
     SEQAN_CALL_TEST(test_modified_string_padding_end);
     SEQAN_CALL_TEST(test_modified_string_padding_difference);
     SEQAN_CALL_TEST(test_modified_string_padding_iterator);
+    SEQAN_CALL_TEST(test_modified_string_padding_defect_2190);
 }
 SEQAN_END_TESTSUITE
diff --git a/tests/modifier/test_modifier_string_padding.h b/tests/modifier/test_modifier_string_padding.h
index 063b620..b474429 100644
--- a/tests/modifier/test_modifier_string_padding.h
+++ b/tests/modifier/test_modifier_string_padding.h
@@ -181,4 +181,28 @@ SEQAN_DEFINE_TEST(test_modified_string_padding_iterator)
     SEQAN_ASSERT_EQ(*(it - 3), seq[12]);
 }
 
+SEQAN_DEFINE_TEST(test_modified_string_padding_defect_2190)
+{
+    using namespace seqan;
+
+    DnaString seq = "ACGTGGATAGCATCG";
+    auto seqInf = infix(seq, 0, length(seq));
+
+    auto test_const = [](auto const & modifier)
+    {
+        // using TRef = typename Reference<decltype(modifier)>::Type;
+        auto x = value(modifier, 1);
+        SEQAN_ASSERT_EQ(x, 'C');
+    };
+    { // Test working case, when reference of const modifier gives back a const reference to the value
+        ModifiedString<decltype(seq), ModPadding> modString(seq);
+        test_const(modString);
+    }
+
+    {  // Test defect, when reference of const modifier gives back a non-const reference to the value
+        ModifiedString<decltype(seqInf), ModPadding> modString(seqInf);
+        test_const(modString);
+    }
+}
+
 #endif  // #ifndef TESTS_MODIFIER_MODIFIER_STRING_PADDING_H_
diff --git a/tests/multiple_translation_units/test_multiple_translation_units.cpp b/tests/multiple_translation_units/test_multiple_translation_units.cpp
index 650820e..c1202be 100644
--- a/tests/multiple_translation_units/test_multiple_translation_units.cpp
+++ b/tests/multiple_translation_units/test_multiple_translation_units.cpp
@@ -34,6 +34,7 @@
 
 #include <seqan/align.h>
 #include <seqan/align_extend.h>
+#include <seqan/align_parallel.h>
 #include <seqan/align_profile.h>
 #include <seqan/align_split.h>
 #include <seqan/alignment_free.h>
diff --git a/tests/multiple_translation_units/test_multiple_translation_units_2.cpp b/tests/multiple_translation_units/test_multiple_translation_units_2.cpp
index 0040c65..dff56a2 100644
--- a/tests/multiple_translation_units/test_multiple_translation_units_2.cpp
+++ b/tests/multiple_translation_units/test_multiple_translation_units_2.cpp
@@ -36,6 +36,7 @@
 
 #include <seqan/align.h>
 #include <seqan/align_extend.h>
+#include <seqan/align_parallel.h>
 #include <seqan/align_profile.h>
 #include <seqan/align_split.h>
 #include <seqan/alignment_free.h>
diff --git a/tests/parallel/CMakeLists.txt b/tests/parallel/CMakeLists.txt
index 245675d..0df6d73 100644
--- a/tests/parallel/CMakeLists.txt
+++ b/tests/parallel/CMakeLists.txt
@@ -39,7 +39,9 @@ add_executable (test_parallel
                test_parallel_atomic_misc.h
                test_parallel_atomic_primitives.h
                test_parallel_splitting.h
-               test_parallel_queue.h)
+               test_parallel_queue.h
+               test_parallel_thread_pool.h
+               test_parallel_enumerable_thread_local.h)
 
 # Add dependencies found by find_package (SeqAn).
 target_link_libraries (test_parallel ${SEQAN_LIBRARIES})
diff --git a/tests/parallel/test_parallel.cpp b/tests/parallel/test_parallel.cpp
index 452cf2a..a4f5904 100755
--- a/tests/parallel/test_parallel.cpp
+++ b/tests/parallel/test_parallel.cpp
@@ -47,6 +47,8 @@
 #include "test_parallel_splitting.h"
 #include "test_parallel_algorithms.h"
 #include "test_parallel_queue.h"
+#include "test_parallel_thread_pool.h"
+#include "test_parallel_enumerable_thread_local.h"
 
 SEQAN_BEGIN_TESTSUITE(test_parallel) {
 #if defined(_OPENMP)
@@ -96,5 +98,24 @@ SEQAN_BEGIN_TESTSUITE(test_parallel) {
 //        SEQAN_CALL_TEST(test_parallel_queue_mpmc_fixedsize);
 //        SEQAN_CALL_TEST(test_parallel_queue_mpmc_dynamicsize);
     }
+
+    // -----------------------------------------------------------------------
+    // Test thread pool.
+    // -----------------------------------------------------------------------
+
+    SEQAN_CALL_TEST(test_parallel_thread_pool_construct);
+    SEQAN_CALL_TEST(test_parallel_thread_pool_spawn);
+    SEQAN_CALL_TEST(test_parallel_thread_pool_join);
+    SEQAN_CALL_TEST(test_parallel_thread_pool_destruct);
+
+    // -----------------------------------------------------------------------
+    // Test Enumerable Thread Specific.
+    // -----------------------------------------------------------------------
+
+    SEQAN_CALL_TEST(test_parallel_enumerable_thread_local_construct);
+    SEQAN_CALL_TEST(test_parallel_enumerable_thread_local_local);
+    SEQAN_CALL_TEST(test_parallel_enumerable_thread_local_enumerate);
+    SEQAN_CALL_TEST(test_parallel_enumerable_thread_local_combine_unary);
+    SEQAN_CALL_TEST(test_parallel_enumerable_thread_local_combine_binary);
 }
 SEQAN_END_TESTSUITE
diff --git a/tests/parallel/test_parallel_enumerable_thread_local.h b/tests/parallel/test_parallel_enumerable_thread_local.h
new file mode 100644
index 0000000..1a124dd
--- /dev/null
+++ b/tests/parallel/test_parallel_enumerable_thread_local.h
@@ -0,0 +1,217 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#include <algorithm>
+
+#include <seqan/parallel.h>
+
+namespace test_align_parallel
+{
+struct TestValue
+{
+    std::string mMsg{"default constructed"};
+
+    //NOTE(rrahn) Bug in g++-4.9 prevents us from using as aggregate type.
+    TestValue() = default;
+
+    TestValue(std::string const _msg) : mMsg(std::move(_msg))
+    {}
+};
+
+template <typename TEtl>
+inline void
+run(TEtl & tls, size_t const threadCount)
+{
+    unsigned counter{0};
+    std::mutex mutexCout;
+    // spawn sveral threads that call for a number of repetitions the local variable.
+    auto task = [&counter, &mutexCout, &tls](unsigned const tid)
+    {
+        while (true)
+        {
+            auto & val = local(tls);
+            if (val.first == "master")
+            {
+                std::stringstream ss;
+                ss << "thread_" << tid;
+                val.first = ss.str();
+            }
+            {
+                std::lock_guard<std::mutex> lck(mutexCout);
+                if (counter == 1000)
+                    break;
+                ++counter;
+            }
+            --val.second;
+        }
+    };
+
+    std::vector<std::thread> pool;
+    for (unsigned tid = 0; tid < threadCount; ++tid)
+        pool.emplace_back(task, tid);
+
+    std::for_each(std::begin(pool), std::end(pool),
+                  [](auto & thread)
+                  {
+                      if (thread.joinable())
+                          thread.join();
+                  });
+}
+
+template <typename TEtl>
+void
+testEnumerate(TEtl & etl)
+{
+    unsigned count{0};
+
+    for (auto it = begin(etl); it != end(etl); ++it)
+    {
+        count += 1000 - it->second;
+    }
+    SEQAN_ASSERT_EQ(count, 1000u);
+}
+
+template <typename TEtl>
+void
+testEnumerateConst(TEtl const & etl)
+{
+    unsigned count{0};
+
+    for (auto it = begin(etl); it != end(etl); ++it)
+    {
+        count += 1000 - it->second;
+    }
+    SEQAN_ASSERT_EQ(count, 1000u);
+}
+
+}
+
+SEQAN_DEFINE_TEST(test_parallel_enumerable_thread_local_construct)
+{
+    using namespace seqan;
+
+    SEQAN_ASSERT(std::is_default_constructible<EnumerableThreadLocal<int>>::value);
+    SEQAN_ASSERT(!std::is_copy_constructible<EnumerableThreadLocal<int>>::value);
+    SEQAN_ASSERT(!std::is_move_constructible<EnumerableThreadLocal<int>>::value);
+    SEQAN_ASSERT(!std::is_copy_assignable<EnumerableThreadLocal<int>>::value);
+    SEQAN_ASSERT(!std::is_move_assignable<EnumerableThreadLocal<int>>::value);
+
+    {  // Default construction.
+        EnumerableThreadLocal<test_align_parallel::TestValue> tls;
+        SEQAN_ASSERT_EQ(tls._initValue.mMsg, "default constructed");
+    }
+
+    {  // Predefined initialization value.
+        EnumerableThreadLocal<test_align_parallel::TestValue> tls{test_align_parallel::TestValue{"predefined"}};
+        SEQAN_ASSERT_EQ(tls._initValue.mMsg, "predefined");
+    }
+}
+
+SEQAN_DEFINE_TEST(test_parallel_enumerable_thread_local_local)
+{
+    using namespace seqan;
+
+    using TPair = std::pair<std::string, unsigned>;
+    EnumerableThreadLocal<TPair> tls{TPair{"master", 1000}};
+
+    size_t threadCount = std::min(std::thread::hardware_concurrency(), static_cast<unsigned>(4));
+    test_align_parallel::run(tls, threadCount);
+
+    SEQAN_ASSERT_EQ(tls._map.size(), threadCount);
+
+    std::for_each(std::begin(tls._map), std::end(tls._map),
+    [](auto const & mapValue)
+    {
+        auto const& val = mapValue.second;
+        SEQAN_ASSERT_NEQ(val.first, "master");
+        SEQAN_ASSERT_LEQ(val.second, 1000u);
+        SEQAN_ASSERT_GEQ(val.second, 0u);
+    });
+}
+
+SEQAN_DEFINE_TEST(test_parallel_enumerable_thread_local_enumerate)
+{
+    using namespace seqan;
+
+    using TPair = std::pair<std::string, unsigned>;
+    EnumerableThreadLocal<TPair> tls{TPair{"master", 1000}};
+
+    size_t threadCount = std::min(std::thread::hardware_concurrency(), static_cast<unsigned>(4));
+    test_align_parallel::run(tls, threadCount);
+
+    SEQAN_ASSERT_EQ(tls._map.size(), threadCount);
+
+    test_align_parallel::testEnumerate(tls);
+    test_align_parallel::testEnumerateConst(tls);
+}
+
+SEQAN_DEFINE_TEST(test_parallel_enumerable_thread_local_combine_unary)
+{
+    using namespace seqan;
+
+    using TPair = std::pair<std::string, unsigned>;
+    EnumerableThreadLocal<TPair> tls{TPair{"master", 1000}};
+
+    size_t threadCount = std::min(std::thread::hardware_concurrency(), static_cast<unsigned>(4));
+    test_align_parallel::run(tls, threadCount);
+
+    SEQAN_ASSERT_EQ(tls._map.size(), threadCount);
+
+    unsigned count{0};
+    combineEach(tls, [&](TPair const & p)
+    {
+        count += 1000 - p.second;
+    });
+    SEQAN_ASSERT_EQ(count, 1000u);
+}
+
+SEQAN_DEFINE_TEST(test_parallel_enumerable_thread_local_combine_binary)
+{
+    using namespace seqan;
+
+    using TPair = std::pair<std::string, unsigned>;
+    EnumerableThreadLocal<TPair> tls{TPair{"master", 1000}};
+
+    size_t threadCount = std::min(std::thread::hardware_concurrency(), static_cast<unsigned>(4));
+    test_align_parallel::run(tls, threadCount);
+
+    SEQAN_ASSERT_EQ(tls._map.size(), threadCount);
+
+    TPair count = combine(tls, [](TPair const & initial, TPair const & val)
+                          {
+                              return TPair{initial.first, initial.second + (1000 - val.second)};
+                          });
+    SEQAN_ASSERT_EQ(count.first, "");
+    SEQAN_ASSERT_EQ(count.second, 1000u);
+}
diff --git a/tests/parallel/test_parallel_thread_pool.h b/tests/parallel/test_parallel_thread_pool.h
new file mode 100644
index 0000000..9940234
--- /dev/null
+++ b/tests/parallel/test_parallel_thread_pool.h
@@ -0,0 +1,151 @@
+// ==========================================================================
+//                 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: Rene Rahn <rene.rahn at fu-berlin.de>
+// ==========================================================================
+
+#include <seqan/parallel.h>
+
+SEQAN_DEFINE_TEST(test_parallel_thread_pool_construct)
+{
+    using namespace seqan;
+    // We need to be able to construct a thread pool.
+    SEQAN_ASSERT(std::is_default_constructible<ThreadPool>::value);
+    SEQAN_ASSERT(!std::is_copy_constructible<ThreadPool>::value);
+    SEQAN_ASSERT(!std::is_move_constructible<ThreadPool>::value);
+    SEQAN_ASSERT(!std::is_copy_assignable<ThreadPool>::value);
+    SEQAN_ASSERT(!std::is_move_assignable<ThreadPool>::value);
+}
+
+SEQAN_DEFINE_TEST(test_parallel_thread_pool_spawn)
+{
+    using namespace seqan;
+    // We need to be able to construct a thread pool
+    ThreadPool pool;
+    bool res = false;
+    auto masterId = std::this_thread::get_id();
+    spawn(pool, [=, &res]()
+    {
+        auto id = std::this_thread::get_id();
+        res = id != masterId;
+    });
+
+    join(pool);
+    SEQAN_ASSERT(res);
+}
+
+SEQAN_DEFINE_TEST(test_parallel_thread_pool_join)
+{
+    using namespace seqan;
+
+    ThreadPool pool;
+    std::vector<bool> res{false, false};
+    for (unsigned i = 0; i < res.size(); ++i)
+    {
+        auto f = [=, &res]
+        {
+            std::this_thread::sleep_for(std::chrono::seconds(i));
+            res[i] = true;
+        };
+        spawn(pool, f);
+    }
+
+    SEQAN_ASSERT_NOT(std::accumulate(std::begin(res), std::end(res), true,
+                                     [](bool const lhs, bool const rhs)
+                                     {
+                                         return lhs && rhs;
+                                     }));
+    join(pool);
+    SEQAN_ASSERT(std::accumulate(std::begin(res), std::end(res), true,
+                                 [](bool const lhs, bool const rhs)
+                                 {
+                                     return lhs && rhs;
+                                 }));
+}
+
+SEQAN_DEFINE_TEST(test_parallel_thread_pool_destruct)
+{
+    using namespace seqan;
+
+    { // Destructor.
+        void* buffer = malloc(sizeof(ThreadPool));
+        ThreadPool* poolPtr = new(buffer) ThreadPool();
+
+        bool res = false;
+        auto f = [&res]()
+        {
+            std::this_thread::sleep_for(std::chrono::seconds(1));
+            res = true;
+        };
+        spawn(*poolPtr, f);
+        SEQAN_ASSERT_NOT(res);
+
+        try
+        {
+            poolPtr->~ThreadPool();
+        }
+        catch(...)
+        {
+            SEQAN_ASSERT_FAIL("Could not savely destruct thread pool!");
+        }
+        SEQAN_ASSERT(res);
+
+        free(buffer);
+    }
+
+    {  // Destructor after join
+        void* buffer = malloc(sizeof(ThreadPool));
+        ThreadPool* poolPtr = new(buffer) ThreadPool();
+
+        bool res = false;
+        auto f = [&res]()
+        {
+            std::this_thread::sleep_for(std::chrono::seconds(1));
+            res = true;
+        };
+        spawn(*poolPtr, f);
+        SEQAN_ASSERT_NOT(res);
+        join(*poolPtr);
+        SEQAN_ASSERT(res);
+
+        try
+        {
+            poolPtr->~ThreadPool();
+        }
+        catch(...)
+        {
+            SEQAN_ASSERT_FAIL("Could not savely destruct thread pool!");
+        }
+        SEQAN_ASSERT(res);
+
+        free(buffer);
+    }
+}
diff --git a/tests/seeds/test_seeds_global_chaining.cpp b/tests/seeds/test_seeds_global_chaining.cpp
index 3cb5b82..f9e729f 100644
--- a/tests/seeds/test_seeds_global_chaining.cpp
+++ b/tests/seeds/test_seeds_global_chaining.cpp
@@ -116,6 +116,32 @@ SEQAN_DEFINE_TEST(test_seeds_global_chaining_sparse_length)
         SEQAN_ASSERT_EQ(1u, length(result));
         SEQAN_ASSERT_EQ(TSeed(0, 93, 281, 342), result[0]);
     }
+
+    { // Issue #2082
+       TSeedSet seedSet;
+
+       addSeed(seedSet, TSeed(0, 0, 3), Single());
+       addSeed(seedSet, TSeed(2, 3, 2), Single());
+
+       TSeedChain result;
+       chainSeedsGlobally(result, seedSet, SparseChaining());
+
+       SEQAN_ASSERT_EQ(1u, length(result));
+       SEQAN_ASSERT_EQ(TSeed(0, 0, 3), result[0]);
+   }
+
+   { // Issue #2082
+        TSeedSet seedSet;
+
+        addSeed(seedSet, TSeed(0, 0, 100), Single());
+        addSeed(seedSet, TSeed(95, 95, 10), Single());
+
+        TSeedChain result;
+        chainSeedsGlobally(result, seedSet, SparseChaining());
+
+        SEQAN_ASSERT_EQ(1u, length(result));
+        SEQAN_ASSERT_EQ(TSeed(0, 0, 100), result[0]);
+    }
 }
 
 SEQAN_BEGIN_TESTSUITE(test_seeds_global_chaining)
diff --git a/tests/simd/test_simd_vector.h b/tests/simd/test_simd_vector.h
index 822f271..7e6ea54 100644
--- a/tests/simd/test_simd_vector.h
+++ b/tests/simd/test_simd_vector.h
@@ -108,7 +108,8 @@ void reverseIndexSequence(TSimdVector & idx, TSize length)
 template <typename TSimdVector>
 constexpr auto trueValue()
 {
-    using TValue = typename Value<TSimdVector>::Type;
+    using TSimdMaskVector = typename SimdMaskVector<TSimdVector>::Type;
+    using TValue = typename Value<TSimdMaskVector>::Type;
     return static_cast<TValue>(-1);
 }
 
@@ -369,6 +370,7 @@ SEQAN_TYPED_TEST(SimdVectorTestCommon, CmpEqual)
 {
     using namespace seqan;
     using TSimdVector = typename TestFixture::TSimdVector;
+    using TSimdMaskVector = typename SimdMaskVector<TSimdVector>::Type;
     using TValue = typename TestFixture::TValue;
     using TBoolValue = decltype(trueValue<TSimdVector>());
     constexpr auto length = TestFixture::LENGTH;
@@ -383,7 +385,7 @@ SEQAN_TYPED_TEST(SimdVectorTestCommon, CmpEqual)
     a[1] = 23;
     b[1] = 23;
 
-    auto c = cmpEq(a, b);
+    TSimdMaskVector c = cmpEq(a, b);
 
     for (auto i = 0; i < length; ++i)
     {
@@ -399,6 +401,7 @@ SEQAN_TYPED_TEST(SimdVectorTestCommon, CmpGt)
 {
     using namespace seqan;
     using TSimdVector = typename TestFixture::TSimdVector;
+    using TSimdMaskVector = typename SimdMaskVector<TSimdVector>::Type;
     using TValue = typename TestFixture::TValue;
     using TBoolValue = decltype(trueValue<TSimdVector>());
     constexpr auto length = TestFixture::LENGTH;
@@ -409,7 +412,7 @@ SEQAN_TYPED_TEST(SimdVectorTestCommon, CmpGt)
     TSimdVector a{0u}, b{0u};
     fillVectors(a, b);
 
-    auto c = cmpGt(a, b);
+    TSimdMaskVector c = cmpGt(a, b);
 
     for (auto i = 0; i < length; ++i)
     {
diff --git a/tests/translation/test_translation.h b/tests/translation/test_translation.h
index 50bbdbb..6dba4e7 100644
--- a/tests/translation/test_translation.h
+++ b/tests/translation/test_translation.h
@@ -598,6 +598,42 @@ test_translation_stringset_multiframe_impl0()
 
         test_translation_stringset_multiframe_impl(comp, source, TParallelism());
     }
+
+    // handle empty input sequences correctly, see #2228
+    {
+        // one empty input results in 6 empty output frames for consistency
+        insertValue(comp,  0, "");
+        insertValue(comp,  1, "");
+        insertValue(comp,  2, "");
+        insertValue(comp,  3, "");
+        insertValue(comp,  4, "");
+        insertValue(comp,  5, "");
+
+        // too short for anything also results in six empty
+        insertValue(comp,  6, "");
+        insertValue(comp,  7, "");
+        insertValue(comp,  8, "");
+        insertValue(comp,  9, "");
+        insertValue(comp, 10, "");
+        insertValue(comp, 11, "");
+
+        // too short for shift results in some empty frames
+        insertValue(comp, 12, "T");
+        insertValue(comp, 13, "");
+        insertValue(comp, 14, "");
+        insertValue(comp, 15, "R");
+        insertValue(comp, 16, "");
+        insertValue(comp, 17, "");
+
+        StringSet<Dna5String, TSetSpec> source;
+        appendValue(source, ""); // empty
+        appendValue(source, "a"); // empty
+        appendValue(source, "acg"); // some empty frames
+        appendValue(source, "acgtnncgtaaaccgttaaaccgnntaagtnnaccccggtaccgataan");
+        appendValue(source, "ggttacgtatnntaccggttagtacttggggcgagtaganngtt");
+
+        test_translation_stringset_multiframe_impl(comp, source, TParallelism());
+    }
 }
 
 SEQAN_DEFINE_TEST(test_translation_stringset_multiframe_serial)
diff --git a/tests/vcf_io/example_records_with_errors.vcf b/tests/vcf_io/example_records_with_errors.vcf
index f7a04e7..e00f079 100644
--- a/tests/vcf_io/example_records_with_errors.vcf
+++ b/tests/vcf_io/example_records_with_errors.vcf
@@ -1,6 +1,8 @@
 20	14370	rs6054257	G	A	29	PASS	NS=3;DP=14;AF=0.5;DB;H2	GT:GQ:DP:HQ	0|0:48:1:51,51	1|0:48:8:51,51	1/1:43:5:.,.
 20	17330	.	T	A	3	q10	NS=3;DP=11;AF=0.017	GT:GQ:DP:HQ	0|0:49:3:58,50	0|1:3:5:65,3	0/0:41:3
 20	1110696	rs6040355	A	G,T	67	PASS	NS=2;DP=10;AF=0.333,0.667;AA=T;DB	GT:GQ:DP:HQ	1|2:21:6:23,27	2|1:2:0:18,2	2/2:35:4
+20	1110696	rs6040355	A	G,T	67	PASS	NS=2;DP=10;AF=0.333,0.667;AA=T;DB	0|0:49:3:58,50	2|1:2:0:18,2	2/2:35:4
+20	1110696	rs6040355	A	G,T	67	PASS	NS=2;DP=10;AF=0.333,0.667;AA=T;DB	0|0:49:3:58,50	1|2:21:6:23,27	2|1:2:0:18,2	
 20
 20	
 20	1110696
@@ -19,6 +21,3 @@
 20	1110696	rs6040355	A	G,T	67	PASS	NS=2;DP=10;AF=0.333,0.667;AA=T;DB	GT:GQ:DP:HQ	2/2:35:4
 20	1110696	rs6040355	A	G,T	67	PASS	NS=2;DP=10;AF=0.333,0.667;AA=T;DB	GT:GQ:DP:HQ	2/2:35:4	
 20	1110696	rs6040355	A	G,T	67	PASS	NS=2;DP=10;AF=0.333,0.667;AA=T;DB	GT:GQ:DP:HQ		2/2:35:4
-20	1110696	rs6040355	A	G,T	67	PASS	NS=2;DP=10;AF=0.333,0.667;AA=T;DB	GT:GQ:DP:HQ	2|1:2:0:18,2	2/2:35:4
-20	1110696	rs6040355	A	G,T	67	PASS	NS=2;DP=10;AF=0.333,0.667;AA=T;DB	GT:GQ:DP:HQ	1|2:21:6:23,27	2|1:2:0:18,2		
-
diff --git a/tests/vcf_io/test_vcf_io.h b/tests/vcf_io/test_vcf_io.h
index c9d1852..cab9957 100644
--- a/tests/vcf_io/test_vcf_io.h
+++ b/tests/vcf_io/test_vcf_io.h
@@ -118,13 +118,13 @@ SEQAN_DEFINE_TEST(test_vcf_io_read_vcf_record)
 
     seqan::String<seqan::VcfRecord> records;
     seqan::VcfRecord record;
-    for (unsigned i = 0; i < 3; ++i)
+    for (unsigned i = 0; i < 5; ++i)
     {
         readRecord(record, vcfIOContext, iter, seqan::Vcf());
         appendValue(records, record);
     }
 
-    SEQAN_ASSERT_EQ(length(records), 3u);
+    SEQAN_ASSERT_EQ(length(records), 5u);
 
     SEQAN_ASSERT_EQ(records[0].rID, 0);
     SEQAN_ASSERT_EQ(records[0].beginPos, 14369);
@@ -159,11 +159,35 @@ SEQAN_DEFINE_TEST(test_vcf_io_read_vcf_record)
     SEQAN_ASSERT_EQ(records[2].format, "GT:GQ:DP:HQ");
     SEQAN_ASSERT_EQ(length(records[2].genotypeInfos), 3u);
 
+    // the next 2 recodrs are valid since vcf v4.2
+    SEQAN_ASSERT_EQ(records[3].rID, 0);
+    SEQAN_ASSERT_EQ(records[3].beginPos, 1110695);
+    SEQAN_ASSERT_EQ(records[3].id, "rs6040355");
+    SEQAN_ASSERT_EQ(records[3].ref, "A");
+    SEQAN_ASSERT_EQ(records[3].alt, "G,T");
+    SEQAN_ASSERT_EQ(records[3].qual, 67);
+    SEQAN_ASSERT_EQ(records[3].filter, "PASS");
+    SEQAN_ASSERT_EQ(records[3].info, "NS=2;DP=10;AF=0.333,0.667;AA=T;DB");
+    SEQAN_ASSERT_EQ(records[3].format, ""); // empty formats are accepted since v4.2
+    SEQAN_ASSERT_EQ(length(records[3].genotypeInfos), 3u);
+
+    SEQAN_ASSERT_EQ(records[4].rID, 0);
+    SEQAN_ASSERT_EQ(records[4].beginPos, 1110695);
+    SEQAN_ASSERT_EQ(records[4].id, "rs6040355");
+    SEQAN_ASSERT_EQ(records[4].ref, "A");
+    SEQAN_ASSERT_EQ(records[4].alt, "G,T");
+    SEQAN_ASSERT_EQ(records[4].qual, 67);
+    SEQAN_ASSERT_EQ(records[4].filter, "PASS");
+    SEQAN_ASSERT_EQ(records[4].info, "NS=2;DP=10;AF=0.333,0.667;AA=T;DB");
+    SEQAN_ASSERT_EQ(records[4].format, ""); // empty formats are accepted since v4.2
+    SEQAN_ASSERT_EQ(length(records[4].genotypeInfos), 3u);
+
+    // the next 18 records are invalid and readRecord should throw ParseError
+    // continuing to read after EOF file should also result in ParseError
     for (unsigned i = 0; i < 25; ++i)
     {
         SEQAN_TEST_EXCEPTION(seqan::ParseError,
                              seqan::readRecord(record, vcfIOContext, iter, seqan::Vcf()));
-        seqan::skipLine(iter);
     }
 }
 
diff --git a/util/cmake/SeqAnBuildSystem.cmake b/util/cmake/SeqAnBuildSystem.cmake
index e642f81..7839478 100644
--- a/util/cmake/SeqAnBuildSystem.cmake
+++ b/util/cmake/SeqAnBuildSystem.cmake
@@ -37,6 +37,14 @@
 # build system.
 # ============================================================================
 
+# ----------------------------------------------------------------------------
+# Set CMAKE policies.
+# ----------------------------------------------------------------------------
+
+if (POLICY CMP0054)  # Disables auto-dereferencing of variables in quoted statements
+  cmake_policy(SET CMP0054 NEW)
+endif()
+
 # Valid values for SEQAN_BUILD_SYSTEM:
 #
 # DEVELOP
@@ -53,6 +61,12 @@ set(PythonInterp_FIND_VERSION_COUNT 2)
 include (SeqAnUsabilityAnalyzer)
 include (CheckCXXCompilerFlag)
 
+if (DEFINED CMAKE_INSTALL_DOCDIR)
+    set(CMAKE_INSTALL_DOCDIR_IS_SET ON)
+endif ()
+
+include (GNUInstallDirs)
+
 set (COMPILER_CLANG FALSE)
 set (COMPILER_GCC FALSE)
 set (COMPILER_LINTEL FALSE)
@@ -206,7 +220,7 @@ macro (seqan_build_system_init)
         # TODO(h-2): raise this to W4
         set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} /W3")
     else()
-        set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -W -Wall -pedantic -fstrict-aliasing -Wstrict-aliasing")
+        set (SEQAN_CXX_FLAGS "${SEQAN_CXX_FLAGS} -W -Wall -pedantic")
         set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64)
 
         # disable some warnings on ICC
@@ -389,24 +403,24 @@ macro (seqan_setup_library)
         install (FILES LICENSE
                        README.rst
                        CHANGELOG.rst
-                 DESTINATION share/doc/seqan)
+                 DESTINATION ${CMAKE_INSTALL_DOCDIR})
         # Install pkg-config file, except on Windows.
         if (NOT CMAKE_SYSTEM_NAME MATCHES Windows)
             configure_file("util/pkgconfig/seqan.pc.in" "${CMAKE_BINARY_DIR}/util/pkgconfig/seqan-${SEQAN_VERSION_MAJOR}.pc" @ONLY)
-            install(FILES "${CMAKE_BINARY_DIR}/util/pkgconfig/seqan-${SEQAN_VERSION_MAJOR}.pc" DESTINATION lib/pkgconfig)
+            install(FILES "${CMAKE_BINARY_DIR}/util/pkgconfig/seqan-${SEQAN_VERSION_MAJOR}.pc" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig)
         endif (NOT CMAKE_SYSTEM_NAME MATCHES Windows)
         # Install FindSeqAn TODO(h-2) rename seqan-config.cmake to seqan-config${SEQAN_VERSION_MAJOR}.cmake after 2.x cycle
-        install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/util/cmake/seqan-config.cmake" DESTINATION lib/cmake/seqan/)
+        install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/util/cmake/seqan-config.cmake" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/seqan/)
 
         # Install headers
         file (GLOB HEADERS
-              RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+              RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/include/
               include/seqan/[A-z]*/[A-z]/[A-z]*.h
               include/seqan/[A-z]*/[A-z]*.h
               include/seqan/[A-z]*.h)
         foreach (HEADER ${HEADERS})
             get_filename_component (_DESTINATION ${HEADER} PATH)
-            install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} DESTINATION ${_DESTINATION})
+            install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/${HEADER} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${_DESTINATION})
         endforeach ()
     endif ()
 
@@ -463,8 +477,11 @@ macro (seqan_setup_install_vars APP_NAME)
         set (SEQAN_PREFIX_SHARE ".")
         set (SEQAN_PREFIX_SHARE_DOC ".")
     else ()
-        set (SEQAN_PREFIX_SHARE "share/${APP_NAME}")
-        set (SEQAN_PREFIX_SHARE_DOC "share/doc/${APP_NAME}")
+        if (NOT DEFINED CMAKE_INSTALL_DOCDIR_IS_SET)
+            set (CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc" CACHE STRING "Documentation root (DATAROOTDIR/doc)" FORCE)
+        endif ()
+        set (SEQAN_PREFIX_SHARE "${CMAKE_INSTALL_DATADIR}/${APP_NAME}")
+        set (SEQAN_PREFIX_SHARE_DOC "${CMAKE_INSTALL_DOCDIR}/${APP_NAME}")
     endif ()
 endmacro (seqan_setup_install_vars)
 
diff --git a/util/cmake/SeqAnSimdUtility.cmake b/util/cmake/SeqAnSimdUtility.cmake
index e48d46c..87adb3c 100644
--- a/util/cmake/SeqAnSimdUtility.cmake
+++ b/util/cmake/SeqAnSimdUtility.cmake
@@ -285,22 +285,38 @@ int main() {
   return 0;
 }")
 
-set(SEQAN_SIMD_SEQANSIMD_AVX512_SKX_SOURCE
+set(SEQAN_SIMD_SEQANSIMD_AVX512_KNL_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;
 
+  {
+    using int8x32_t = signed char __attribute__ ((__vector_size__(32)));
+    unsigned length = sizeof(int8x32_t) / sizeof(char);
+    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;
+  }
+
+  // gcc 5.0 bug
+  // -std=c++14 -mavx512f -O3
+  {
+    using int8x64_t = signed char __attribute__ ((__vector_size__(64)));
+    unsigned length = sizeof(int8x64_t) / sizeof(char);
+    int8x64_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;
 }")
 
@@ -409,13 +425,13 @@ macro(detect_simd_support)
 
         # 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)
+            set(CMAKE_REQUIRED_FLAGS "${SEQAN_SIMD_AVX512_KNL_FLAGS}")
+            check_cxx_simd_source_runs("${SEQAN_SIMD_SEQANSIMD_AVX512_KNL_SOURCE}" SEQANSIMD_AVX512_KNL_SOURCE_RUNS)
 
-            if (SEQANSIMD_AVX512_SKX_SOURCE_RUNS_COMPILED)
+            if (SEQANSIMD_AVX512_KNL_SOURCE_RUNS_COMPILED)
                 set(_SEQANSIMD_SUPPORTED "${SEQAN_SIMD_SUPPORTED_EXTENSIONS}")
             else ()
-                simd_list_version_less(_SEQANSIMD_SUPPORTED "avx512_skx")
+                simd_list_version_less(_SEQANSIMD_SUPPORTED "avx512_knl")
             endif()
         endif()
 
diff --git a/util/cmake/seqan-config.cmake b/util/cmake/seqan-config.cmake
index 55e9691..5be6084 100644
--- a/util/cmake/seqan-config.cmake
+++ b/util/cmake/seqan-config.cmake
@@ -85,6 +85,14 @@ include(CheckIncludeFileCXX)
 include(CheckCXXSourceCompiles)
 
 # ----------------------------------------------------------------------------
+# Set CMAKE policies.
+# ----------------------------------------------------------------------------
+
+if (POLICY CMP0054)  # Disables auto-dereferencing of variables in quoted statements
+  cmake_policy(SET CMP0054 NEW)
+endif()
+
+# ----------------------------------------------------------------------------
 # Define Constants.
 # ----------------------------------------------------------------------------
 
@@ -158,9 +166,9 @@ elseif (COMPILER_CLANG)
 
 elseif (COMPILER_LINTEL OR COMPILER_WINTEL)
 
-    # require at least icpc 16.0.2
-    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0.2)
-        message(AUTHOR_WARNING "Intel Compiler version (${CMAKE_CXX_COMPILER_VERSION}) should be at least 16.0.2! Anything below is untested.")
+    # require at least icpc 17.0.0
+    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 17.0.0)
+        message(AUTHOR_WARNING "Intel Compiler version (${CMAKE_CXX_COMPILER_VERSION}) should be at least 17.0.0! Anything below is untested.")
     endif ()
 
 elseif (COMPILER_MSVC)
@@ -238,9 +246,8 @@ endif (WIN32)
 # Visual Studio Setup
 if (COMPILER_MSVC OR COMPILER_WINTEL)
   # Enable intrinics (e.g. _interlockedIncrease)
-  # /EHsc will be set automatically for COMPILER_MSVC and COMPILER_WINTEL, but
   # COMPILER_CLANG (clang/c2 3.7) can not handle the /EHsc and /Oi flag
-  set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} /Oi)
+  set (SEQAN_DEFINITIONS ${SEQAN_DEFINITIONS} /EHsc /Oi)
 endif ()
 
 # ----------------------------------------------------------------------------
diff --git a/util/pkgconfig/seqan.pc.in b/util/pkgconfig/seqan.pc.in
index 8cc5f3f..7dc4a00 100644
--- a/util/pkgconfig/seqan.pc.in
+++ b/util/pkgconfig/seqan.pc.in
@@ -1,6 +1,4 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-includedir=${prefix}/include
+includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
 
 Name: @CMAKE_PROJECT_NAME@
 Description: C++ library for biological sequence analysis
diff --git a/util/skel/app_template/CMakeLists.txt b/util/skel/app_template/CMakeLists.txt
index 6d1aeca..1c72c2b 100644
--- a/util/skel/app_template/CMakeLists.txt
+++ b/util/skel/app_template/CMakeLists.txt
@@ -48,7 +48,7 @@ endif (NOT SEQAN_PREFIX_SHARE_DOC)
 
 # Install %(NAME)s in ${PREFIX}/bin directory
 install (TARGETS %(NAME)s
-         DESTINATION bin)
+         DESTINATION ${CMAKE_INSTALL_BINDIR})
 
 # Install non-binary files for the package to "." for app builds and
 # ${PREFIX}/share/doc/%(NAME)s for SeqAn release builds.
diff --git a/util/travis/linux-cibuild.cmake b/util/travis/linux-cibuild.cmake
index 714ac24..35574ed 100644
--- a/util/travis/linux-cibuild.cmake
+++ b/util/travis/linux-cibuild.cmake
@@ -21,7 +21,6 @@ set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS 1000)
 set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS 1000)
 set(CTEST_CUSTOM_WARNING_EXCEPTION "statically linked applications")
 
-
 # Use 4 build threads
 set(CTEST_BUILD_FLAGS -j2)
 
diff --git a/util/travis/linux-cibuild.sh b/util/travis/linux-cibuild.sh
index 14627a8..97fb55f 100755
--- a/util/travis/linux-cibuild.sh
+++ b/util/travis/linux-cibuild.sh
@@ -18,6 +18,11 @@ if [ "$(echo ${CXX} | cut -c1-5)" = "clang" ]; then
   export CXXFLAGS="${CXXFLAGS} -Qunused-arguments -DSEQAN_IGNORE_MISSING_OPENMP=1"
 fi
 
+# compile with c++-17 if g++-7 is used.
+if [ "$(echo ${CXX})" = "g++-7" ]; then
+  export CXXFLAGS="${CXXFLAGS} -std=c++17"
+fi
+
 # Switch version check default to OFF to prevent checks during app tests
 CXXFLAGS="${CXXFLAGS} -DSEQAN_VERSION_CHECK_OPT_IN=YES"
 

-- 
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