Author: Michael R. Crusoe <michael.crusoe@gmail.com>
Description: python3 conversion
--- seqan2.orig/apps/bs_tools/tests/run_tests.py
+++ seqan2/apps/bs_tools/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for bs_tools.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -24,9 +24,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for bs_tools'
-    print '========================='
-    print
+    print('Executing test for bs_tools')
+    print('=========================')
+    print()
    
     ##############################################################
     ### Casbar
@@ -226,7 +226,7 @@
                     ph.outFile('meths_pe_0.bed'))])
         conf_list.append(conf)
     else:
-        print "Some tests only run on Linux+x86/amd64 because of rounding differences."
+        print("Some tests only run on Linux+x86/amd64 because of rounding differences.")
 
 
     # ============================================================
@@ -235,22 +235,22 @@
     failures = 0
     for conf in conf_list:
         # Output to the user.
-        print ' '.join([os.path.basename(conf.program)] + conf.args)
+        print(' '.join([os.path.basename(conf.program)] + conf.args))
         res = app_tests.runTest(conf)
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
 
 
     # Compute and return return code.
--- seqan2.orig/apps/dfi/tests/run_tests.py
+++ seqan2/apps/dfi/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the pair_align program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,7 +23,7 @@
 
 def unzip_file_into_dir(file, dir):
     if not os.path.exists(dir):
-        os.mkdir(dir, 0777)
+        os.mkdir(dir, 0o777)
     zfobj = zipfile.ZipFile(file)
     for name in zfobj.namelist():
         if name.endswith('/'):
@@ -37,9 +37,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for dfi'
-    print '======================'
-    print
+    print('Executing test for dfi')
+    print('======================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -84,21 +84,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['dfi'] + conf.args),
+        print(' '.join(['dfi'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/fiona/tests/run_tests.py
+++ seqan2/apps/fiona/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the fiona program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -38,7 +38,7 @@
                     '-g', self.path_to_ref,
                     '--pre', self.path_to_sam,
                     '--post', self.path_to_post]
-        print ' '.join(cmd_line)
+        print(' '.join(cmd_line))
         process = subprocess.Popen(cmd_line, stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
         stdoutbuff, stderrbuff = process.communicate()
@@ -55,9 +55,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for fiona'
-    print '========================'
-    print
+    print('Executing test for fiona')
+    print('========================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -161,21 +161,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(conf.commandLineArgs())
+        print(' '.join(conf.commandLineArgs()))
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/gustaf/tests/run_tests.py
+++ seqan2/apps/gustaf/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for program gustaf.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for gustaf'
-    print '==============================='
-    print
+    print('Executing test for gustaf')
+    print('===============================')
+    print()
 
     ph = app_tests.TestPathHelper(
          source_base, binary_base,
@@ -383,21 +383,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['gustaf'] + conf.args),
+        print(' '.join(['gustaf'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/insegt/tests/run_tests.py
+++ seqan2/apps/insegt/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for insegt.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for insegt'
-    print '========================='
-    print
+    print('Executing test for insegt')
+    print('=========================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -138,21 +138,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['insegt'] + conf.args),
+        print(' '.join(['insegt'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/mason2/tests/run_tests.py
+++ seqan2/apps/mason2/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the mason_variator program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for mason_variator'
-    print '======================'
-    print
+    print('Executing test for mason_variator')
+    print('======================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -46,7 +46,7 @@
     path_to_simulator = app_tests.autolocateBinary(
       binary_base, 'bin', 'mason_simulator')
 
-    libcpp = (os.environ.has_key('CC') and 'gcc' in os.environ["CC"]) or sys.platform == "linux" or sys.platform == "linux2"
+    libcpp = ('CC' in os.environ and 'gcc' in os.environ["CC"]) or sys.platform == "linux" or sys.platform == "linux2"
 
     # ============================================================
     # Built TestConf list.
@@ -546,21 +546,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join([os.path.basename(conf.program)] + conf.args),
+        print(' '.join([os.path.basename(conf.program)] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/micro_razers/tests/run_tests.py
+++ seqan2/apps/micro_razers/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for micro_razers.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for micro_razers'
-    print '==============================='
-    print
+    print('Executing test for micro_razers')
+    print('===============================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -127,21 +127,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['micro_razers'] + conf.args),
+        print(' '.join(['micro_razers'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/ngs_roi/tests/run_tests.py
+++ seqan2/apps/ngs_roi/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the roi_intersect program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for roi_intersect'
-    print '================================'
-    print
+    print('Executing test for roi_intersect')
+    print('================================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -120,21 +120,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join([os.path.basename(conf.program)] + conf.args),
+        print(' '.join([os.path.basename(conf.program)] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/ngs_roi/tool_shed/ctd2galaxy.py
+++ seqan2/apps/ngs_roi/tool_shed/ctd2galaxy.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Conversion of the CTD format into Galaxy XML.
 
 The CTD parser should be reusable but is not in its own module since it is
@@ -103,13 +103,13 @@
             self.path.append(self.name)
         if not self.children:
             return  # nothing to do: early exit.
-        for name, child in self.children.items():
+        for name, child in list(self.children.items()):
             child.computePath(False, self.path)
 
     def applyFunc(self, f):
         """Apply f to self and all children."""
         f(self)
-        for c in self.children.values():
+        for c in list(self.children.values()):
             c.applyFunc(f)
             
     def find(self, path):
@@ -315,7 +315,7 @@
     def appendTag(self, tag, text='', args={}):
         """Append a tag to self.result with text content only or no content at all."""
         e = xml.sax.saxutils.quoteattr
-        args_str = ' '.join('%s=%s' % (key, e(str(value))) for key, value in args.items() if value is not None)
+        args_str = ' '.join('%s=%s' % (key, e(str(value))) for key, value in list(args.items()) if value is not None)
         if args_str:
             args_str = ' '+ args_str
         vals = {'indent': self.indent(),
@@ -330,7 +330,7 @@
     def openTag(self, tag, args={}):
         """Append an opening tag to self.result."""
         e = xml.sax.saxutils.quoteattr
-        args_str = ' '.join('%s=%s' % (key, e(str(value))) for key, value in args.items())
+        args_str = ' '.join('%s=%s' % (key, e(str(value))) for key, value in list(args.items()))
         if args_str:
             args_str = ' ' + args_str
         vals = {'indent': self.indent(),
@@ -345,7 +345,7 @@
 
     def handleParameters(self, node):
         """Recursion for appending tags for ParametersNode."""
-        for pn in node.children.values():
+        for pn in list(node.children.values()):
             if pn.kind in ['item', 'itemlist']:
                 args = {'name': pn.name,
                         'value': pn.value,
--- seqan2.orig/apps/ngs_roi/tool_shed/ngs_roi/app.py
+++ seqan2/apps/ngs_roi/tool_shed/ngs_roi/app.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Support code for writing the NGS ROI report generation apps."""
 
 __author__    = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
@@ -56,12 +56,12 @@
                     '--plot-width', self.args.plot_width,
                     '--border-width', self.args.border_width,
                     '--spacing', self.args.spacing]
-        cmd_args = ['roi_plot_thumbnails'] + map(str, cmd_args)
+        cmd_args = ['roi_plot_thumbnails'] + list(map(str, cmd_args))
         #import pdb; pdb.set_trace()
         import sys
-        print >>sys.stderr, 'Running %s' % ' '.join(cmd_args)
+        print('Running %s' % ' '.join(cmd_args), file=sys.stderr)
         p = subprocess.Popen(cmd_args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
         res = p.wait()
         if res:
-            print 'ERROR', p.stdin, p.stderr
+            print('ERROR', p.stdin, p.stderr)
         return res
--- seqan2.orig/apps/ngs_roi/tool_shed/ngs_roi/argparse.py
+++ seqan2/apps/ngs_roi/tool_shed/ngs_roi/argparse.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Helper for ROI tools when using argparse module.
 
 This module contains helper functions for setup of argparse.ArgumentParser
--- seqan2.orig/apps/ngs_roi/tool_shed/ngs_roi/io.py
+++ seqan2/apps/ngs_roi/tool_shed/ngs_roi/io.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Input / Output Routines for ROI files.
 
 You can load the records sequentially one by one by iterating over a
@@ -107,7 +107,7 @@
         """Return iterator (self)."""
         return self
 
-    def next(self):
+    def __next__(self):
         """Return next record."""
         if self.line == '':  # EOF
             raise StopIteration
--- seqan2.orig/apps/ngs_roi/tool_shed/roi_details.py
+++ seqan2/apps/ngs_roi/tool_shed/roi_details.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Generation of detailed ROI reports with larger plots.
 
 This report generation works for hundred of ROIs.
@@ -73,7 +73,7 @@
 
         :return: integer with the result.
         """
-        print >>sys.stderr, 'Loading ROI'
+        print('Loading ROI', file=sys.stderr)
         records = ngs_roi.io.load(self.args.in_file, self.args.max_rois)
         keys = records[0].data_keys
 
@@ -90,7 +90,7 @@
         for i, roi in enumerate(records):
             file_name = 'plot_%d.png' % i
             file_name = os.path.join(self.args.out_dir, file_name)
-            print >>sys.stderr, 'Writing plot %s' % file_name
+            print('Writing plot %s' % file_name, file=sys.stderr)
             plt.figure(figsize=(4, 2.5))
             plt.gcf().subplots_adjust(bottom=0.16, left=0.15)
             plt.plot(roi.points, color=COLOR, linewidth=LINE_WIDTH, linestyle=LINE_STYLE)
@@ -104,7 +104,7 @@
 
     def writeHtml(self, keys, records):
         file_name = self.args.out_file
-        print >>sys.stderr, 'Writing HTML file %s' % file_name
+        print('Writing HTML file %s' % file_name, file=sys.stderr)
 
         vals = {'args': self.args, 'records': records, 'data_keys': keys,
                 'href': lambda x: self.buildHref(x.ref, x.start_pos, x.end_pos)}
--- seqan2.orig/apps/ngs_roi/tool_shed/roi_plot_thumbnails.py
+++ seqan2/apps/ngs_roi/tool_shed/roi_plot_thumbnails.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Thumbnail Plot Generator.
 
 This report generator uses the binary roi_plot_thumbnails (C++ program, must
@@ -112,14 +112,14 @@
 
     def run(self):
         # Load ROI records.
-        print >>sys.stderr, 'Loading ROI'
+        print('Loading ROI', file=sys.stderr)
 
         # Create plots.
         runner = ngs_roi.app.PlotThumbnailsRunner(self.args)
         runner.run()
 
         # Create HTML.
-        print >>sys.stderr, 'Creating HTML...'
+        print('Creating HTML...', file=sys.stderr)
         num_plots = self.args.num_cols * self.args.num_rows  # plots on grid
         for i, roi in enumerate(ngs_roi.io.RoiFile(self.args.in_file)):
             if self.args.max_rois > 0 and i >= self.args.max_rois:
@@ -127,13 +127,13 @@
             # Write out old grid (if any) and create new one.
             if i % num_plots == 0:
                 if self.grid:
-                    print >>sys.stderr, '  Writing plot %d...' % self.plot_idx
+                    print('  Writing plot %d...' % self.plot_idx, file=sys.stderr)
                 self.writeGrid()
                 self.grid = RoiPlotGrid(self.args.plot_width, self.args.plot_height,
                                         self.args.num_cols, self.args.num_rows)
             # Put the next plot on the grid.
             self.grid.plotRecord(roi)
-        print >>sys.stderr, '  Writing plot %d...' % self.plot_idx
+        print('  Writing plot %d...' % self.plot_idx, file=sys.stderr)
         self.writeGrid()  # Write last grid.
         self.createHtml(self.args.out_file)
         return 0
@@ -149,7 +149,7 @@
         self.grid_links.append(GridLinks(os.path.basename(file_name), self.grid.link_regions))
 
     def createHtml(self, file_name):
-        print >>sys.stderr, 'Writing HTML to %s' % file_name
+        print('Writing HTML to %s' % file_name, file=sys.stderr)
         with open(file_name, 'wb') as f:
             f.write('<html><body>\n')
             f.write('<h1>ROI Thumbnail Plots</h1>')
--- seqan2.orig/apps/ngs_roi/tool_shed/roi_report.py
+++ seqan2/apps/ngs_roi/tool_shed/roi_report.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Create ROI overview report.
 
 This report consists of plots of all metrics (y: metric, x: rank of value).
@@ -8,7 +8,7 @@
 Plotting is done using the fine matplotlib.
 """
 
-from __future__ import print_function
+
 
 __author__    = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
 __copyright__ = 'Copyring 2013, Freie Universitaet Berlin'
--- seqan2.orig/apps/ngs_roi/tool_shed/roi_table.py
+++ seqan2/apps/ngs_roi/tool_shed/roi_table.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """ROI Table Generator
 
 Generates a HTML page with a table of ROI record details.  Besides showing the
@@ -90,7 +90,7 @@
 
     def tplFuncs(self):
         def intWithCommas(x):
-            if type(x) not in [type(0), type(0L)]:
+            if type(x) not in [type(0), type(0)]:
                 raise TypeError("Parameter must be an integer.")
             if x < 0:
                 return '-' + intWithCommas(-x)
@@ -138,24 +138,24 @@
 
     def run(self):
         # Load ROI records.
-        print >>sys.stderr, 'Loading ROI'
+        print('Loading ROI', file=sys.stderr)
         records = ngs_roi.io.load(self.args.in_file, self.args.max_rois)
         keys = []
         if records:
             keys = records[0].data_keys
 
         # Create plots.
-        print >>sys.stderr, 'Creating plots...'
+        print('Creating plots...', file=sys.stderr)
         runner = ngs_roi.app.PlotThumbnailsRunner(self.args)
         runner.run()
 
         # Create table.
-        print >>sys.stderr, 'Creating table...'
+        print('Creating table...', file=sys.stderr)
         self.createHtml(self.args.out_file, keys, records)
         return 0
 
     def createHtml(self, file_name, keys, records):
-        print >>sys.stderr, 'Writing %s' % self.args.out_file
+        print('Writing %s' % self.args.out_file, file=sys.stderr)
         vals = {'table': RoiTable(self.args, keys, records, self).render(),
                 'args': self.args}
         t = Cheetah.Template.Template(PAGE_TPL, searchList=vals)
--- seqan2.orig/apps/ngs_roi/tool_shed/rois.py
+++ seqan2/apps/ngs_roi/tool_shed/rois.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 
 class RoiRecord(object):
     """Represent one record in a ROI file."""
--- seqan2.orig/apps/pair_align/tests/run_tests.py
+++ seqan2/apps/pair_align/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the pair_align program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for pair_align'
-    print '============================='
-    print
+    print('Executing test for pair_align')
+    print('=============================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -229,21 +229,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['pair_align'] + conf.args),
+        print(' '.join(['pair_align'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/rabema/tests/run_tests.py
+++ seqan2/apps/rabema/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for rabema.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -24,9 +24,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for rabema'
-    print '========================='
-    print
+    print('Executing test for rabema')
+    print('=========================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -162,21 +162,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join([os.path.basename(conf.program)] + conf.args),
+        print(' '.join([os.path.basename(conf.program)] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/razers/gapped_params/dat2cpp.py
+++ seqan2/apps/razers/gapped_params/dat2cpp.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Convert RazerS gapped params .dat file to C++ fragment."""
 
 USAGE = 'dat2cpp.py INPUT.dat'
@@ -26,7 +26,7 @@
 def main():
     # Check arguments.
     if len(sys.argv) == 1:
-        print >>sys.stderr, USAGE
+        print(USAGE, file=sys.stderr)
         return 1
     # Process each file.
     records = []
@@ -38,10 +38,10 @@
         d = t[1]
         with open(fname, 'rb') as f:
             records += parseFile(f, n, d)
-    print '/* Gapped params.  Generated by dat2cpp.py. */\n'
+    print('/* Gapped params.  Generated by dat2cpp.py. */\n')
     for r in sorted(records):
-        print '{ %s },' % ', '.join(map(str, r))
-    print '{ 0, \'\\0\', 0, 0, 0, 0, 0 } /* terminator */'
+        print('{ %s },' % ', '.join(map(str, r)))
+    print('{ 0, \'\\0\', 0, 0, 0, 0, 0 } /* terminator */')
 
 if __name__ == '__main__':
     sys.exit(main())
--- seqan2.orig/apps/razers/tests/run_tests.py
+++ seqan2/apps/razers/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the pair_align program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -26,13 +26,13 @@
 
     # gold standard binary files created on little endian
     if platform.machine().startswith('mips64'):
-        print 'Skipping tests for Razers on mips64el'
-        print '====================================='
+        print('Skipping tests for Razers on mips64el')
+        print('=====================================')
         return 0
 
-    print 'Executing test for razers'
-    print '========================='
-    print
+    print('Executing test for razers')
+    print('=========================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -262,21 +262,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['razers'] + conf.args),
+        print(' '.join(['razers'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/razers3/tests/run_tests.py
+++ seqan2/apps/razers3/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the razers3 program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -43,9 +43,9 @@
 def main(source_base, binary_base, num_threads=1):
     """Main entry point of the script."""
 
-    print 'Executing test for razers3'
-    print '==========================='
-    print
+    print('Executing test for razers3')
+    print('===========================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -306,21 +306,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['razers3'] + conf.args),
+        print(' '.join(['razers3'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/razers3/tests/run_tests_sequential.py
+++ seqan2/apps/razers3/tests/run_tests_sequential.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Sequential tests (num_threads == 0) for RazerS 3.
 
 See run_tests.py for the actual tests.  We only call the code from there.
--- seqan2.orig/apps/sak/tests/run_tests.py
+++ seqan2/apps/sak/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the sak program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for sak'
-    print '======================'
-    print
+    print('Executing test for sak')
+    print('======================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -137,21 +137,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(conf.commandLineArgs())
+        print(' '.join(conf.commandLineArgs()))
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/sam2matrix/tests/run_tests.py
+++ seqan2/apps/sam2matrix/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for sam2matrix.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for sam2matrix'
-    print '============================='
-    print
+    print('Executing test for sam2matrix')
+    print('=============================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -71,21 +71,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['sam2matrix'] + conf.args),
+        print(' '.join(['sam2matrix'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/samcat/tests/run_tests.py
+++ seqan2/apps/samcat/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the samcat program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for samcat'
-    print '========================='
-    print
+    print('Executing test for samcat')
+    print('=========================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -75,21 +75,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(conf.commandLineArgs())
+        print(' '.join(conf.commandLineArgs()))
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/searchjoin/tests/run_tests.py
+++ seqan2/apps/searchjoin/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for search/join.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -31,13 +31,13 @@
     """Main entry point of the script."""
 
     if platform.machine().startswith('alpha'):
-        print 'Skipping tests for searchjoin on alpha'
-        print '======================================'
+        print('Skipping tests for searchjoin on alpha')
+        print('======================================')
         return 0
 
-    print 'Executing test for searchjoin'
-    print '==========================='
-    print
+    print('Executing test for searchjoin')
+    print('===========================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -128,21 +128,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join([conf.program] + conf.args),
+        print(' '.join([conf.program] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/seqan_tcoffee/tests/run_tests.py
+++ seqan2/apps/seqan_tcoffee/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the seqan_tcoffee program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -25,13 +25,13 @@
     """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 '==================================================='
+        print('Skipping tests for seqan_tcoffee on mips* and s390*')
+        print('===================================================')
         return 0
 
-    print 'Executing test for seqan_tcoffee'
-    print '================================'
-    print
+    print('Executing test for seqan_tcoffee')
+    print('================================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -251,21 +251,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['seqan_tcoffee'] + conf.args),
+        print(' '.join(['seqan_tcoffee'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/seqcons2/tests/run_tests.py
+++ seqan2/apps/seqcons2/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the seqcons2 program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for seqcons2'
-    print '==========================='
-    print
+    print('Executing test for seqcons2')
+    print('===========================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -154,21 +154,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join([os.path.basename(conf.program)] + conf.args),
+        print(' '.join([os.path.basename(conf.program)] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/sgip/tests/run_tests.py
+++ seqan2/apps/sgip/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for sgip.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for sgip'
-    print '========================='
-    print
+    print('Executing test for sgip')
+    print('=========================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -139,21 +139,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['sgip'] + conf.args),
+        print(' '.join(['sgip'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/snp_store/tests/run_tests.py
+++ seqan2/apps/snp_store/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for snp_store.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for snp_store'
-    print '========================='
-    print
+    print('Executing test for snp_store')
+    print('=========================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -161,21 +161,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['snp_store'] + conf.args),
+        print(' '.join(['snp_store'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/splazers/tests/run_tests.py
+++ seqan2/apps/splazers/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for splazers.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -23,9 +23,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for splazers'
-    print '========================='
-    print
+    print('Executing test for splazers')
+    print('=========================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -183,21 +183,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['splazers'] + conf.args),
+        print(' '.join(['splazers'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/stellar/tests/run_tests.py
+++ seqan2/apps/stellar/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for stellar.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -24,9 +24,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for stellar'
-    print '========================='
-    print
+    print('Executing test for stellar')
+    print('=========================')
+    print()
 
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -203,20 +203,20 @@
     # ============================================================
     failures = 0
     for conf in conf_list:
-        print ' '.join(['stellar'] + conf.args)
+        print(' '.join(['stellar'] + conf.args))
         res = app_tests.runTest(conf)
         # Output to the user.
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/tree_recon/tests/run_tests.py
+++ seqan2/apps/tree_recon/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for the tree_recomb program.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -22,9 +22,9 @@
 def main(source_base, binary_base):
     """Main entry point of the script."""
 
-    print 'Executing test for tree_recomb'
-    print '=============================='
-    print
+    print('Executing test for tree_recomb')
+    print('==============================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -79,21 +79,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join(['tree_recomb'] + conf.args),
+        print(' '.join(['tree_recomb'] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/apps/yara/tests/run_tests.py
+++ seqan2/apps/yara/tests/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for Yara.
 
 The golden test outputs are generated by the script generate_outputs.sh.
@@ -35,13 +35,13 @@
 
     # gold standard binary files created on little endian
     if sys.byteorder != 'little':
-        print 'Skipping tests for Yara on big endian'
-        print '====================================='
+        print('Skipping tests for Yara on big endian')
+        print('=====================================')
         return 0
 
-    print 'Executing test for Yara'
-    print '=============================='
-    print
+    print('Executing test for Yara')
+    print('==============================')
+    print()
     
     ph = app_tests.TestPathHelper(
         source_base, binary_base,
@@ -118,21 +118,21 @@
     for conf in conf_list:
         res = app_tests.runTest(conf)
         # Output to the user.
-        print ' '.join([conf.program] + conf.args),
+        print(' '.join([conf.program] + conf.args), end=' ')
         if res:
-             print 'OK'
+             print('OK')
         else:
             failures += 1
-            print 'FAILED'
+            print('FAILED')
 
     # Cleanup.
     ph.deleteTempDir()
 
-    print '=============================='
-    print '     total tests: %d' % len(conf_list)
-    print '    failed tests: %d' % failures
-    print 'successful tests: %d' % (len(conf_list) - failures)
-    print '=============================='
+    print('==============================')
+    print('     total tests: %d' % len(conf_list))
+    print('    failed tests: %d' % failures)
+    print('successful tests: %d' % (len(conf_list) - failures))
+    print('==============================')
     # Compute and return return code.
     return failures != 0
 
--- seqan2.orig/manual/source/Infrastructure/Manage/WriteAppTests.rst
+++ seqan2/manual/source/Infrastructure/Manage/WriteAppTests.rst
@@ -173,7 +173,7 @@
 
 .. code-block:: python
 
-   #!/usr/bin/env python2
+   #!/usr/bin/env python3
    """Execute the tests for upcase.
 
    The golden test outputs are generated by the script generate_outputs.sh.
--- seqan2.orig/util/bin/auto_build.py
+++ seqan2/util/bin/auto_build.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """SeqAn Automatic Build System."""
 
 import os.path
--- seqan2.orig/util/bin/dddoc.py
+++ seqan2/util/bin/dddoc.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """SeqAn Documentation System DDDoc."""
 
 import os.path
--- seqan2.orig/util/bin/demo_checker.py
+++ seqan2/util/bin/demo_checker.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Demo checker script.
 
 Given a demo .cpp file PATH.cpp we can make it a small test if there is a file
@@ -32,7 +32,7 @@
         use the literal [VAR] if the part of the output is not expected to be the same all the time.
     """
     if len(pattern) != len(text):
-        print >> sys.stderr, 'Number of lines differ. Expected output has %s lines whereas actual has %s lines.' % (len(pattern), len(text))
+        print('Number of lines differ. Expected output has %s lines whereas actual has %s lines.' % (len(pattern), len(text)), file=sys.stderr)
         return False
     for i in range(len(pattern)):
         T = text[i]
@@ -41,13 +41,13 @@
             continue
         else :
             if '[VAR]' not in P:
-                print >> sys.stderr, 'Line %s is different between expected and actual outputs.' % (i)
+                print('Line %s is different between expected and actual outputs.' % (i), file=sys.stderr)
                 return False
             else:
                 P = (re.escape(P)).replace('\\[VAR\\]', "[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?")
                 r = re.compile(P)
                 if re.match(r, T) == None:
-                    print >> sys.stderr, 'Line %s is different (REGEX) between expected and actual outputs.' % (i)
+                    print('Line %s is different (REGEX) between expected and actual outputs.' % (i), file=sys.stderr)
                     return False
     return True
 
@@ -83,35 +83,35 @@
                         default=None)
     args = parser.parse_args()
 
-    print >>sys.stderr, 'Running %s.' % args.binary_path
+    print('Running %s.' % args.binary_path, file=sys.stderr)
     actual_out, actual_err, ret = runDemo(args)
 
     if ret != 0:
-        print >>sys.stderr, 'ERROR: Return code of %s was %s.' % (args.binary_path, ret)
+        print('ERROR: Return code of %s was %s.' % (args.binary_path, ret), file=sys.stderr)
         return 1
     else:
-        print >>sys.stderr, 'Return code was %s.' % ret
+        print('Return code was %s.' % ret, file=sys.stderr)
 
-    print >>sys.stderr, 'Loading files "%s", "%s".' % (args.stdout_path, args.stderr_path)
+    print('Loading files "%s", "%s".' % (args.stdout_path, args.stderr_path), file=sys.stderr)
     expected_out, expected_err = loadExpected(args)
     is_stdout_as_expected = fuzzyEqual(expected_out, actual_out)
     is_stderr_as_expected = fuzzyEqual(expected_err, actual_err)
 
     if not is_stdout_as_expected:
-        print >>sys.stderr, 'The standard output was not as expected!'
+        print('The standard output was not as expected!', file=sys.stderr)
         l = difflib.context_diff(expected_out, actual_out,
                                  fromfile='expected', tofile='actual')
-        print >>sys.stderr, '\n'.join(l)
+        print('\n'.join(l), file=sys.stderr)
     else:
-        print >>sys.stderr, 'Standard output was as expected.'
+        print('Standard output was as expected.', file=sys.stderr)
 
     if not is_stderr_as_expected:
-        print >>sys.stderr, 'The standard error was not as expected!'
+        print('The standard error was not as expected!', file=sys.stderr)
         l = difflib.context_diff(expected_err, actual_err,
                                  fromfile='expected', tofile='actual')
-        print >>sys.stderr, '\n'.join(l)
+        print('\n'.join(l), file=sys.stderr)
     else:
-        print >>sys.stderr, 'Standard error was as expected.'
+        print('Standard error was as expected.', file=sys.stderr)
 
     # here we used not because we need return-code 0 (False) if test is successful 
     return not (is_stdout_as_expected and is_stderr_as_expected)
--- seqan2.orig/util/bin/dox.py
+++ seqan2/util/bin/dox.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """SeqAn doxygen-style documentation system."""
 
 import os.path
--- seqan2.orig/util/bin/fixgcov.py
+++ seqan2/util/bin/fixgcov.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Fix gcov output.
 
 Fix gcov output with templates.  This is done by first parsing in the .cpp files
--- seqan2.orig/util/bin/profile2pdf.py
+++ seqan2/util/bin/profile2pdf.py
@@ -1,10 +1,10 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Convert SeqAn profiling information into PDF graphic.
 
 USAGE: profile2pdf.py <program.profile.txt> <out.pdf>
 """
 
-from __future__ import with_statement
+
 
 __author__ = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
 
@@ -38,11 +38,11 @@
     colorstring = colorstring.strip()
     if colorstring[0] == '#': colorstring = colorstring[1:]
     if len(colorstring) != 6:
-        raise ValueError, "input #%s is not in #RRGGBB format" % colorstring
+        raise ValueError("input #%s is not in #RRGGBB format" % colorstring)
     r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:]
     r, g, b = [int(n, 16) for n in (r, g, b)]
     return (r / 255.0, g / 255.0, b / 255.0)
-COLORS = map(htmlColorToRgb, COLORS)  
+COLORS = list(map(htmlColorToRgb, COLORS))  
 
 class Meta(object):
   def __init__(self, beginTimestamp, endTimestamp):
@@ -61,7 +61,7 @@
   def fromString(klass, s):
     columns = s.split('\t')
     if columns[0] != '@EVENT':
-      print >>sys.stderr, 'First column\'s value was not "@EVENT@'
+      print('First column\'s value was not "@EVENT@', file=sys.stderr)
       sys.exit(1)
     identifier = int(columns[1])
     shortName = columns[2]
@@ -88,7 +88,7 @@
     columns = s.split('\t')
     threadId = int(columns[0])
     if columns[1] not in ['BEGIN', 'END']:
-      print >>sys.stderr, 'Second column\'s value was not BEGIN or END'
+      print('Second column\'s value was not BEGIN or END', file=sys.stderr)
       sys.exit(1)
     isBegin = columns[1] == 'BEGIN'
     jobType = int(columns[2])
@@ -130,7 +130,7 @@
 
 def printSection(section, jobTypes, offset, level=0):
   span = section.endTime - section.beginTime
-  print '%s%s %f  (%f to %f)' % ('\t' * level, jobTypes[section.jobType].shortName, span, section.beginTime - offset, section.endTime - offset)
+  print('%s%s %f  (%f to %f)' % ('\t' * level, jobTypes[section.jobType].shortName, span, section.beginTime - offset, section.endTime - offset))
   for s in section.children:
     printSection(s, jobTypes, offset, level+1)
 
@@ -138,13 +138,13 @@
   with open(path, 'r') as f:
     line = f.readline()
     if line.strip() != '@SQN:PROFILE':
-      print >>sys.stderr, 'Invalid file, does not start with "@SQN:PROFILE"'
+      print('Invalid file, does not start with "@SQN:PROFILE"', file=sys.stderr)
       sys.exit(1)
     line = f.readline()
     if not line.startswith('@TIME'):
-      print >>sys.stderr, 'Invalid file, second line does not start with "@TIME"'
+      print('Invalid file, second line does not start with "@TIME"', file=sys.stderr)
       sys.exit(1)
-    meta = Meta(*map(float, line.strip().split('\t')[1:]))
+    meta = Meta(*list(map(float, line.strip().split('\t')[1:])))
     # Load job types.
     jobTypes = []
     while True:
@@ -248,12 +248,12 @@
 
 def breakDownTimes(jobTypes, forests):
   for threadId in sorted(forests.keys()):
-    print 'Breakdown for thread #%d' % threadId
+    print('Breakdown for thread #%d' % threadId)
     counter = {}
     for section in forests[threadId]:
       breakDownTimesHelper(counter, section)
     for jobType in jobTypes:
-      print '  %20s %10.5f' % (jobType.shortName, counter.get(jobType.identifier, 0))
+      print('  %20s %10.5f' % (jobType.shortName, counter.get(jobType.identifier, 0)))
 
 def createDiagram(meta, jobTypes, forests, path):
   totalBegin = meta.beginTimestamp
@@ -266,7 +266,7 @@
   cs = cairo.PDFSurface(path, width, height)
   cr = cairo.Context(cs)
   
-  for threadId, forest in forests.iteritems():
+  for threadId, forest in forests.items():
     for section in forest:
       drawBoxesForSection(cr, jobTypes, section, totalBegin, threadId)
   drawKey(cr, jobTypes, len(forests))
@@ -276,21 +276,21 @@
 
 def main(args):
   if len(args) != 3:
-    print >>sys.stderr, 'Invalid number of arguments!'
-    print >>sys.stderr, 'USAGE: profile2pdf.py <program.profile.txt> <out.pdf>'
+    print('Invalid number of arguments!', file=sys.stderr)
+    print('USAGE: profile2pdf.py <program.profile.txt> <out.pdf>', file=sys.stderr)
     return 1
   
   # Load input file.
-  print >>sys.stderr, 'Loading file', args[1]
+  print('Loading file', args[1], file=sys.stderr)
   meta, jobTypes, events = loadFile(args[1])
   # Partition events by thread id.
-  print >>sys.stderr, 'Partition events'
+  print('Partition events', file=sys.stderr)
   eventsForThread = {}
   for e in events:
     eventsForThread.setdefault(e.threadId, []).append(e)
 
   # Build sections list and forest for each thread.
-  print >>sys.stderr, 'Build sections'
+  print('Build sections', file=sys.stderr)
   forests = {}
   sections = {}
   for threadId in sorted(eventsForThread.keys()):
@@ -303,12 +303,12 @@
     #  printSection(x, jobTypes, s[0].beginTime)
 
   # Build diagram.
-  print >>sys.stderr, 'Create diagram'
+  print('Create diagram', file=sys.stderr)
   createDiagram(meta, jobTypes, forests, args[2])
 
   # Show how much time each thread spent in each job type.
   breakDownTimes(jobTypes, forests)
-  print 'TOTAL TIME: %f s' % (meta.endTimestamp - meta.beginTimestamp)
+  print('TOTAL TIME: %f s' % (meta.endTimestamp - meta.beginTimestamp))
   
   return 0
 
--- seqan2.orig/util/bin/pyclangcheck.py
+++ seqan2/util/bin/pyclangcheck.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """llvm-clang based style checker."""
 
 __author__ = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
--- seqan2.orig/util/bin/skel.py
+++ seqan2/util/bin/skel.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """SeqAn Skelleton Creation."""
 
 import os.path
--- seqan2.orig/util/ctd2galaxy.py
+++ seqan2/util/ctd2galaxy.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 
 import argparse
 import sys
@@ -182,10 +182,10 @@
 
     ctd_parser = CTDParser()
     tool = ctd_parser.parse(args.in_file)
-    print tool
+    print(tool)
     for cli in tool.cli_elements:
-        print '  %s' % cli
-    print tool.parameters
+        print('  %s' % cli)
+    print(tool.parameters)
         
 
 if __name__ == '__main__':
--- seqan2.orig/util/py_lib/seqan/app_tests.py
+++ seqan2/util/py_lib/seqan/app_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Helper code for app tests.
 
 This module contains helper functions and classes for making app tests easy.
@@ -18,7 +18,7 @@
                                directory.
 """
 
-from __future__ import with_statement
+
 
 __author__ = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
 
@@ -166,7 +166,7 @@
 
     def deleteTempDir(self):
         """Remove the temporary directory created earlier and all files below."""
-        print >>sys.stderr, 'DELETING TEMP DIR', self.temp_dir
+        print('DELETING TEMP DIR', self.temp_dir, file=sys.stderr)
         if self.temp_dir:
             shutil.rmtree(self.temp_dir)
 
@@ -243,20 +243,20 @@
         logging.debug('  return code is %d', retcode)
         if retcode != 0:
             fmt = 'Return code of command "%s" was %d.'
-            print >>sys.stderr, '--- stdout begin --'
-            print >>sys.stderr, fmt % (' '.join(test_conf.commandLineArgs()), retcode)
-            print >>sys.stderr, stdout_file.read()
-            print >>sys.stderr, '--- stdout end --'
+            print('--- stdout begin --', file=sys.stderr)
+            print(fmt % (' '.join(test_conf.commandLineArgs()), retcode), file=sys.stderr)
+            print(stdout_file.read(), file=sys.stderr)
+            print('--- stdout end --', file=sys.stderr)
             stdout_file.close()
             if process.stderr:
                 stderr_contents = process.stderr.read()
             else:
                 stderr_contents = ''
-            print >>sys.stderr, '-- stderr begin --'
-            print >>sys.stderr, stderr_contents
-            print >>sys.stderr, '-- stderr end --'
+            print('-- stderr begin --', file=sys.stderr)
+            print(stderr_contents, file=sys.stderr)
+            print('-- stderr end --', file=sys.stderr)
             return False
-    except Exception, e:
+    except Exception as e:
         # Print traceback.
         import traceback
         exc_type, exc_value, exc_traceback = sys.exc_info()
@@ -264,28 +264,28 @@
         fmt = 'ERROR (when executing "%s"): %s'
         if stdout_file is not subprocess.PIPE:
             stdout_file.close()
-        print >>sys.stderr, fmt % (' '.join(test_conf.commandLineArgs()), e)
+        print(fmt % (' '.join(test_conf.commandLineArgs()), e), file=sys.stderr)
         return False
     # Handle error of program, indicated by return code != 0.
     if retcode != 0:
-        print >>sys.stderr, 'Error when executing "%s".' % ' '.join(test_conf.commandLineArgs())
-        print >>sys.stderr, 'Return code is %d' % retcode
+        print('Error when executing "%s".' % ' '.join(test_conf.commandLineArgs()), file=sys.stderr)
+        print('Return code is %d' % retcode, file=sys.stderr)
         if stdout_file is not subprocess.PIPE:
             stdout_file.seek(0)
         stdout_contents = process.stdout.read()
         if stdout_contents:
-            print >>sys.stderr, '-- stdout begin --'
-            print >>sys.stderr, stdout_contents
-            print >>sys.stderr, '-- stdout end --'
+            print('-- stdout begin --', file=sys.stderr)
+            print(stdout_contents, file=sys.stderr)
+            print('-- stdout end --', file=sys.stderr)
         else:
-            print >>sys.stderr, '-- stdout is empty --'
+            print('-- stdout is empty --', file=sys.stderr)
         stderr_contents = process.stderr.read()
         if stderr_contents:
-            print >>sys.stderr, '-- stderr begin --'
-            print >>sys.stderr, stderr_contents
-            print >>sys.stderr, '-- stderr end --'
+            print('-- stderr begin --', file=sys.stderr)
+            print(stderr_contents, file=sys.stderr)
+            print('-- stderr end --', file=sys.stderr)
         else:
-            print >>sys.stderr, '-- stderr is empty --'
+            print('-- stderr is empty --', file=sys.stderr)
     # Close standard out file if necessary.
     if stdout_file is not subprocess.PIPE:
         stdout_file.close()
@@ -317,7 +317,7 @@
                     continue
                 else:
                     tpl = (expected_path, expected_md5, result_md5, result_path)
-                    print >>sys.stderr, 'md5(gunzip(%s)) == %s != %s == md5(gunzip(%s))' % tpl
+                    print('md5(gunzip(%s)) == %s != %s == md5(gunzip(%s))' % tpl, file=sys.stderr)
                     result = False
             if binary:
                 with open(expected_path, 'rb') as f:
@@ -328,7 +328,7 @@
                     continue
                 else:
                     tpl = (expected_path, expected_md5, result_md5, result_path)
-                    print >>sys.stderr, 'md5(%s) == %s != %s == md5(%s)' % tpl
+                    print('md5(%s) == %s != %s == md5(%s)' % tpl, file=sys.stderr)
                     result = False
             else:
                 with open(expected_path, 'rb') as f:
@@ -342,25 +342,25 @@
                 if expected_str == result_str:
                     continue
                 fmt = 'Comparing %s against %s'
-                print >>sys.stderr, fmt % (expected_path, result_path)
+                print(fmt % (expected_path, result_path), file=sys.stderr)
                 diff = difflib.unified_diff(expected_str.splitlines(),
                                             result_str.splitlines())
                 for line in diff:
-                    print >>sys.stderr, line
+                    print(line, file=sys.stderr)
                 result = False
-        except Exception, e:
+        except Exception as e:
             fmt = 'Error when trying to compare %s to %s: %s ' + str(type(e))
-            print >>sys.stderr, fmt % (expected_path, result_path, e)
+            print(fmt % (expected_path, result_path, e), file=sys.stderr)
             result = False
     # Call check callable.
     if test_conf.check_callback:
         try:
             test_conf.check_callback()
-        except BadResultException, e:
-            print >>sys.stderr, 'Bad result: ' + str(e)
+        except BadResultException as e:
+            print('Bad result: ' + str(e), file=sys.stderr)
             result = False
-        except Exception, e:
-            print >>sys.stderr, 'Error in checker: ' + str(type(e)) + ' ' + str(e)
+        except Exception as e:
+            print('Error in checker: ' + str(type(e)) + ' ' + str(e), file=sys.stderr)
             result = False
     return result
 
--- seqan2.orig/util/py_lib/seqan/auto_build.py
+++ seqan2/util/py_lib/seqan/auto_build.py
@@ -1,9 +1,9 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """
 Automatic building of SeqAn apps and releases.
 """
 
-from __future__ import print_function
+
 
 import subprocess
 import optparse
--- seqan2.orig/util/py_lib/seqan/fixgcov/__init__.py
+++ seqan2/util/py_lib/seqan/fixgcov/__init__.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 
 import sys
 
-import app
+from . import app
 
 main = app.main
 
--- seqan2.orig/util/py_lib/seqan/fixgcov/app.py
+++ seqan2/util/py_lib/seqan/fixgcov/app.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Small libclang based app to fix gcov output.
 
 Fix gcov output with templates.  This is done by first parsing in the .cpp files
@@ -16,7 +16,7 @@
 License:   3-clause BSD (see LICENSE)
 """
 
-from __future__ import with_statement
+
 
 __author__ = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
 
@@ -97,7 +97,7 @@
         if not _hasFileLocation(node):
             return False
         # Try to hit cache.
-        if self.cache.has_key(node.location.file.name):
+        if node.location.file.name in self.cache:
             return self.cache[node.location.file.name]
         # Check whether node's location is below the include directories.  It is
         # only visited if this is the case.
@@ -137,7 +137,7 @@
         # print args
         tu = index.parse(filename, args=args)
         if self.options.verbosity >= 1:
-            print 'Translation unit: %s.' % tu.spelling
+            print('Translation unit: %s.' % tu.spelling)
         return self._recurse(tu.cursor)
     
     @classmethod
@@ -207,17 +207,17 @@
         # lines with compound statements in all included files are written to
         # the location file.
         if options.verbosity >= 1:
-            print >>sys.stderr, 'Building Locations'
+            print('Building Locations', file=sys.stderr)
         if options.verbosity >= 2:
-            print >>sys.stderr, '=================='
+            print('==================', file=sys.stderr)
 
         # Fire off AST traversal.
         if options.verbosity >= 1:
-            print >>sys.stderr, 'AST Traversal'
+            print('AST Traversal', file=sys.stderr)
         node_visitor = CollectCompoundStatementNodeVisitor(options)
         for src in options.source_files:
             if options.verbosity >= 2:
-                print >>sys.stderr, '  Compilation Unit', src
+                print('  Compilation Unit', src, file=sys.stderr)
             AstTraverser.visitFile(src, node_visitor, options)
 
         # Convert locations into points.
@@ -229,7 +229,7 @@
 
         # Write out the source locations.
         if options.verbosity >= 1:
-            print >>sys.stderr, 'Writing out locations to', options.location_file
+            print('Writing out locations to', options.location_file, file=sys.stderr)
         with open(options.location_file, 'wb') as f:
             pickle.dump(locations, f)
 
@@ -240,20 +240,20 @@
     if options.gcov_files:
         # If no source files and gcov files are given then
         if options.verbosity >= 1:
-            print >>sys.stderr, 'Updating gcov Results'
+            print('Updating gcov Results', file=sys.stderr)
         if options.verbosity >= 2:
-            print >>sys.stderr, '====================='
+            print('=====================', file=sys.stderr)
 
         if not options.source_files:
             if options.verbosity >= 1:
-                print >>sys.stderr, 'Loading locations from', options.location_file
+                print('Loading locations from', options.location_file, file=sys.stderr)
             with open(options.location_file, 'rb') as f:
                 locations = pickle.load(f)
 
         for filename in options.gcov_files:
             filename = os.path.abspath(filename)
             if options.verbosity >= 2:
-                print >>sys.stderr, 'Processing', filename
+                print('Processing', filename, file=sys.stderr)
             with open(filename, 'rb') as f:
                 lines = f.readlines()
             pos0 = lines[0].find(':')
@@ -268,9 +268,9 @@
                 txt = line[pos1 + 1:]
                 if txt.startswith('Source:'):
                     source = os.path.abspath(txt[len('Source:'):].strip())
-                    if not locations.has_key(source):
+                    if source not in locations:
                         if options.verbosity >= 2:
-                            print >>sys.stderr, '  Skipping.'
+                            print('  Skipping.', file=sys.stderr)
                         skip = True
                         break
                 if not source or lineno == 0:
--- seqan2.orig/util/py_lib/seqan/paths.py
+++ seqan2/util/py_lib/seqan/paths.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """SeqAn path utilities.
 
 Code to get paths within the SeqAn repository; Useful for setting defaults in
@@ -56,10 +56,10 @@
     return os.path.join(repositoryRoot(), location, filename)
 
 def main(args):
-    print 'SeqAn paths'
-    print
-    print 'repositoryRoot()   ==', repositoryRoot()
-    print 'pathToSkeletons() ==', pathToSkeletons()
+    print('SeqAn paths')
+    print()
+    print('repositoryRoot()   ==', repositoryRoot())
+    print('pathToSkeletons() ==', pathToSkeletons())
 
 if __name__ == '__main__':
    sys.exit(main(sys.argv))
--- seqan2.orig/util/py_lib/seqan/pyclangcheck/__init__.py
+++ seqan2/util/py_lib/seqan/pyclangcheck/__init__.py
@@ -1,8 +1,8 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 
 import sys
 
-import app
+from . import app
 
 main = app.main
 
--- seqan2.orig/util/py_lib/seqan/pyclangcheck/app.py
+++ seqan2/util/py_lib/seqan/pyclangcheck/app.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """pyclangcheck driver code
 
 This code is the driver code for the pyclangcheck tool.
@@ -7,7 +7,7 @@
 License:   3-clause BSD (see LICENSE)
 """
 
-from __future__ import with_statement
+
 
 __author__ = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
 
@@ -19,9 +19,9 @@
 
 import clang.cindex as ci
 
-import simple_checks
-import violations
-import rules
+from . import simple_checks
+from . import violations
+from . import rules
 
 def _hasFileLocation(node):
     """Return True if node has a file lcoation."""
@@ -51,7 +51,7 @@
         self.cache = {}
 
     def get(self, path):
-        if self.cache.has_key(path):
+        if path in self.cache:
             return self.cache[path]
         with open(path, 'rb') as f:
             fcontents = f.readlines()
@@ -106,7 +106,7 @@
                     txt = '<multiline>'
                 else:
                     txt = ''.join(lines).replace('\n', '\\n')
-                print '  ' * len(self.stack), 'Entering', node.kind, node._kind_id, node.spelling, 'txt="%s"' % txt, "%s-%s" % (start, end)
+                print('  ' * len(self.stack), 'Entering', node.kind, node._kind_id, node.spelling, 'txt="%s"' % txt, "%s-%s" % (start, end))
         violations = []
         for rule in self.rules:
             if rule.allowVisit(node):
@@ -155,7 +155,7 @@
         if not _hasFileLocation(node):
             return False
         # Try to hit cache.
-        if self.cache.has_key(node.location.file.name):
+        if node.location.file.name in self.cache:
             return self.cache[node.location.file.name]
         # Check whether the file is blocked.
         if node.location.file.name in self.blocked_files:
@@ -200,14 +200,14 @@
         # print args
         tu = index.parse(filename, args=args)
         if self.options.verbosity >= 1:
-            print 'Translation unit: %s.' % tu.spelling
+            print('Translation unit: %s.' % tu.spelling)
         return self._recurse(tu.cursor)
     
     @classmethod
     def visitFile(klass, filename, node_visitor, options):
         """Don't instantiate AstTraverser yourself, use this function."""
         if options.verbosity >= 1:
-            print >>sys.stderr, 'Checking', filename
+            print('Checking', filename, file=sys.stderr)
         traverser = AstTraverser(node_visitor, options)
         res = traverser.run(filename)
         return res != True
@@ -291,7 +291,7 @@
         res = AstTraverser.visitFile(filename, node_visitor, options)
         node_visitor.seenToBlocked()
         elapsed = datetime.datetime.now() - start
-        print >>sys.stderr, '  took', elapsed.seconds, 's'
+        print('  took', elapsed.seconds, 's', file=sys.stderr)
         if res:
             break
 
@@ -310,7 +310,7 @@
     # Print violations.
     # ========================================================================
 
-    print 'VIOLATIONS'
+    print('VIOLATIONS')
     vs.update(node_visitor.violations)
     printer = violations.ViolationPrinter(options.ignore_nolint,
                                           options.show_source)
--- seqan2.orig/util/py_lib/seqan/pyclangcheck/rules.py
+++ seqan2/util/py_lib/seqan/pyclangcheck/rules.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 
 __author__ = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
 
@@ -7,8 +7,8 @@
 
 import clang.cindex as ci
 
-import app
-import violations
+from . import app
+from . import violations
 
 RULE_NAMING_CONSTANT = 'naming.constant'
 RULE_NAMING_STRUCT = 'naming.struct'
@@ -173,7 +173,7 @@
             return True
         if not app._hasFileLocation(node):
             return False
-        if self.cache.has_key(node.location.file.name):
+        if node.location.file.name in self.cache:
             return self.cache[node.location.file.name]
         # Check whether node's location is below the include directories or one
         # of the source files.
--- seqan2.orig/util/py_lib/seqan/pyclangcheck/simple_checks.py
+++ seqan2/util/py_lib/seqan/pyclangcheck/simple_checks.py
@@ -1,13 +1,13 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Simple source code checks, e.g. trailing whitespace."""
 
-from __future__ import with_statement
+
 
 import bisect
 import re
 import sys
 
-import violations
+from . import violations
 
 RULE_TRAILING_WHITESPACE = 'whitespace.trailing'
 RULE_TEXT_TRAILING_WHITESPACE = 'Trailing whitespace is not allowed.'
@@ -98,7 +98,7 @@
                 match = re.match(RE_TODO, comment)
                 if match:
                     if len(match.group(1)) > 1:
-                        print comment
+                        print(comment)
                         v = violations.SimpleRuleViolation(
                             RULE_TODO_ONE_SPACE, filename, cstart.line,
                             cstart.column, RULE_TEXT_TODO_ONE_SPACE)
--- seqan2.orig/util/py_lib/seqan/pyclangcheck/suppressions.py
+++ seqan2/util/py_lib/seqan/pyclangcheck/suppressions.py
@@ -1 +1 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
--- seqan2.orig/util/py_lib/seqan/pyclangcheck/violations.py
+++ seqan2/util/py_lib/seqan/pyclangcheck/violations.py
@@ -1,14 +1,14 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Code related to violations and suppressions."""
 
-from __future__ import with_statement
+
 
 import os
 import os.path
 import sys
 
-import app
-import rules
+from . import app
+from . import rules
 
 
 class RuleViolation(object):
@@ -54,7 +54,7 @@
     def hasNolint(self, filename, lineno):
         filename = os.path.abspath(filename)
         # Ensure that the nolint lines are registered in self.locations[filename].
-        if not self.locations.has_key(filename):
+        if filename not in self.locations:
             line_set = set()
             with open(filename, 'rb') as f:
                 line_no = 0
@@ -80,12 +80,12 @@
         for k in sorted(vs.keys()):
             violation = vs[k]
             if self.ignore_nolint or not self.nolints.hasNolint(violation.file, violation.line):
-                print violation
+                print(violation)
                 line = self.file_cache.get(violation.file)[violation.line - 1]
                 if self.show_source:
-                    print line.rstrip()
-                    print '%s^' % (' ' * (violation.column - 1))
-                    print
+                    print(line.rstrip())
+                    print('%s^' % (' ' * (violation.column - 1)))
+                    print()
             previous = violation
-        print 'Total: %d violations' % len(vs)
+        print('Total: %d violations' % len(vs))
 
--- seqan2.orig/util/py_lib/seqan/skel.py
+++ seqan2/util/py_lib/seqan/skel.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """SeqAn code generation from templates / skeletons.
 
 This module contains code to help the creation of modules, tests, apps etc.
@@ -28,7 +28,7 @@
 License:   3-clause BSD (see LICENSE)
 """
 
-from __future__ import with_statement
+
 
 __author__ = 'Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>'
 
@@ -39,7 +39,7 @@
 import sys
 import string
 
-import paths
+from . import paths
 
 # Add os.path.relpath if it is not already there, so we can use Python 2.5, too.
 # TODO(holtgrew): This could go into a "compatibility" module.
@@ -111,30 +111,30 @@
 #""".strip()
 
 def createDirectory(path, dry_run=False):
-    print 'mkdir(%s)' % path
-    print
+    print('mkdir(%s)' % path)
+    print()
     if not dry_run:
         if not os.path.exists(path):
             os.mkdir(path)
 
 def configureFile(target_file, source_file, replacements, dry_run, options):
-    print 'Configuring file.'
-    print '  Source:', source_file
-    print '  Target:', target_file
-    print
+    print('Configuring file.')
+    print('  Source:', source_file)
+    print('  Target:', target_file)
+    print()
     if os.path.exists(target_file) and not options.force:
         msg = 'Target file already exists.  Move it away and call the script again.'
-        print >>sys.stderr, msg
+        print(msg, file=sys.stderr)
         return 1
 
     with open(source_file, 'rb') as f:
         contents = f.read()
     target_contents = contents % replacements
     if dry_run:
-        print 'The contents of the target file are:'
-        print '-' * 78
-        print target_contents
-        print '-' * 78
+        print('The contents of the target file are:')
+        print('-' * 78)
+        print(target_contents)
+        print('-' * 78)
     else:
         with open(target_file, 'wb') as f:
             f.write(target_contents)
@@ -177,13 +177,13 @@
     # Check that the given path does not exist yet.
     if os.path.exists(target_path) and not options.force:
         msg = 'The path %s already exists. Move it and call this script again.'
-        print >>sys.stderr, msg % target_path
+        print(msg % target_path, file=sys.stderr)
         return False
     # Check that the parent path already exists.
     if not os.path.exists(os.path.dirname(target_path)):
         msg = 'The parent of the target path does not exist yet: %s'
-        print >>sys.stderr, msg % os.path.dirname(target_path)
-        print >>sys.stderr, 'Please create it and call this script again.'
+        print(msg % os.path.dirname(target_path), file=sys.stderr)
+        print('Please create it and call this script again.', file=sys.stderr)
         return False
     return True
 
@@ -192,14 +192,14 @@
     seqan_path = os.path.join(include_path, 'seqan')
     module_path = os.path.join(seqan_path, name)
     header_path = os.path.join(seqan_path, '%s.h' % name)
-    print 'Creating module in %s' % module_path
+    print('Creating module in %s' % module_path)
     if options.create_dirs and not _checkTargetPaths(module_path, options):
         return 1
     if options.create_dirs and not _checkTargetPaths(header_path, options):
         return 1
-    print '  Module path is: %s' % module_path
-    print '  Module header path is: %s' % header_path
-    print ''
+    print('  Module path is: %s' % module_path)
+    print('  Module header path is: %s' % header_path)
+    print('')
     if options.create_dirs:
         # Create directory.
         createDirectory(module_path, options.dry_run)
@@ -220,11 +220,11 @@
 
 def createTest(name, location, options):
     target_path = paths.pathToTest(location, name)
-    print 'Creating test in %s' % target_path
+    print('Creating test in %s' % target_path)
     if options.create_dirs and not _checkTargetPaths(target_path, options):
         return 1
-    print '  Target path is: %s' % target_path
-    print ''
+    print('  Target path is: %s' % target_path)
+    print('')
     if options.create_dirs:
         # Create directory.
         createDirectory(target_path, options.dry_run)
@@ -252,11 +252,11 @@
 
 def createApp(name, location, options):
     target_path = paths.pathToApp(location, name)
-    print 'Creating app in %s' % target_path
+    print('Creating app in %s' % target_path)
     if options.create_dirs and not _checkTargetPaths(target_path, options):
         return 1
-    print '  Target path is: %s' % target_path
-    print ''
+    print('  Target path is: %s' % target_path)
+    print('')
     if options.create_programs:
         # Create directory.
         createDirectory(target_path, options.dry_run)
@@ -277,11 +277,11 @@
 
 def createDemo(name, location, options):
     target_path = paths.pathToDemo(location, name)
-    print 'Creating demo in %s' % target_path
+    print('Creating demo in %s' % target_path)
     if options.create_dirs and not _checkTargetPaths(target_path, options):
         return 1
-    print '  Target path is: %s' % target_path
-    print ''
+    print('  Target path is: %s' % target_path)
+    print('')
     if options.create_programs:
         # Copy over .cpp file for app and perform replacements.
         source_file = paths.pathToTemplate('demo_template', 'demo.cpp')
@@ -293,27 +293,27 @@
 
 def createHeader(name, location, options):
     target_path = paths.pathToHeader(location, name)
-    print 'Creating (non-library) header in %s' % target_path
+    print('Creating (non-library) header in %s' % target_path)
     if not _checkTargetPaths(target_path, options):
         return 1
-    print '  Target path is: %s' % target_path
-    print ''
+    print('  Target path is: %s' % target_path)
+    print('')
     # Copy over .h file for app and perform replacements.
     source_file = paths.pathToTemplate('header_template', 'header.h')
     target_file = os.path.join(target_path)
     replacements = buildReplacements('header', name, location, target_file, options)
     res = configureFile(target_file, source_file, replacements, options.dry_run, options)
     if res: return res
-    print 'NOTE: Do not forget to add the header to the CMakeLists.txt file!'
+    print('NOTE: Do not forget to add the header to the CMakeLists.txt file!')
     return 0
 
 def createLibraryHeader(name, location, options):
     target_path = paths.pathToHeader(location, name)
-    print 'Creating library header in %s' % target_path
+    print('Creating library header in %s' % target_path)
     if not _checkTargetPaths(target_path, options):
         return 1
-    print '  Target path is: %s' % target_path
-    print ''
+    print('  Target path is: %s' % target_path)
+    print('')
     # Copy over .h file for app and perform replacements.
     source_file = paths.pathToTemplate('header_template', 'library_header.h')
     target_file = os.path.join(target_path)
@@ -323,12 +323,12 @@
     return 0
 
 def createRepository(location, options):
-    print 'Creating module %s' % location
+    print('Creating module %s' % location)
     target_path = paths.pathToRepository(location)
     if options.create_dirs and not _checkTargetPaths(target_path, options):
         return 1
-    print '  Target path is: %s' % target_path
-    print ''
+    print('  Target path is: %s' % target_path)
+    print('')
     if options.create_dirs:
         # Create directories.
         createDirectory(target_path, options.dry_run)
@@ -361,13 +361,13 @@
     return 0
 
 def createAppTests(location, options):
-    print 'Creating app tests at %s' % location
+    print('Creating app tests at %s' % location)
     tests_location = os.path.join(location, 'tests')
     target_path = paths.pathToRepository(tests_location)
     if options.create_dirs and not _checkTargetPaths(target_path, options):
         return 1
-    print '  Target path is: %s' % target_path
-    print ''
+    print('  Target path is: %s' % target_path)
+    print('')
 
     # Create directories.
     if options.create_dirs:
@@ -384,16 +384,16 @@
     replacements = buildReplacements('app_tests', location, target_path, target_file, options)
     configureFile(target_file, source_file, replacements, options.dry_run, options)
 
-    print '=' * 80
-    print 'Do not forget to add the tests in %s:' % os.path.join(location, 'CMakeLists.txt')
-    print ''
-    print '# Add app tests if Python interpreter could be found.'
-    print 'if(PYTHONINTERP_FOUND)'
-    print '  add_test(NAME app_test_%s COMMAND ${PYTHON_EXECUTABLE}' % os.path.split(location)[-1]
-    print '    ${CMAKE_CURRENT_SOURCE_DIR}/tests/run_tests.py ${CMAKE_SOURCE_DIR}'
-    print '    ${CMAKE_BINARY_DIR})'
-    print 'endif(PYTHONINTERP_FOUND)'
-    print '=' * 80
+    print('=' * 80)
+    print('Do not forget to add the tests in %s:' % os.path.join(location, 'CMakeLists.txt'))
+    print('')
+    print('# Add app tests if Python interpreter could be found.')
+    print('if(PYTHONINTERP_FOUND)')
+    print('  add_test(NAME app_test_%s COMMAND ${PYTHON_EXECUTABLE}' % os.path.split(location)[-1])
+    print('    ${CMAKE_CURRENT_SOURCE_DIR}/tests/run_tests.py ${CMAKE_SOURCE_DIR}')
+    print('    ${CMAKE_BINARY_DIR})')
+    print('endif(PYTHONINTERP_FOUND)')
+    print('=' * 80)
     
     return 0
 
@@ -434,15 +434,15 @@
         parser.print_help(file=sys.stderr)
         return 1
     if len(args) < 2:
-        print >>sys.stderr, 'Invalid argument count!'
+        print('Invalid argument count!', file=sys.stderr)
         return 1
     if args[0] not in ['module', 'test', 'app', 'demo', 'repository',
                        'header', 'lheader', 'app_tests']:
-        print >>sys.stderr, 'Invalid template "%s".' % args[0]
+        print('Invalid template "%s".' % args[0], file=sys.stderr)
         return 1
     if args[0] in['repository', 'app_tests']:
         if len(args) != 2:
-            print >>sys.stderr, 'Invalid argument count!'
+            print('Invalid argument count!', file=sys.stderr)
             return 1
 
     if args[0] == 'repository':
@@ -450,7 +450,7 @@
     elif args[0] == 'app_tests':
         return createAppTests(args[1], options)
     elif len(args) != 3:
-        print >>sys.stderr, 'Invalid argument count!'
+        print('Invalid argument count!', file=sys.stderr)
         return 1
     create_methods = {
         'module' : createModule,
--- seqan2.orig/util/skel/app_tests_template/run_tests.py
+++ seqan2/util/skel/app_tests_template/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3
 """Execute the tests for %(APP_NAME)s.
 
 The golden test outputs are generated by the script generate_outputs.sh.
