diff --git a/core/tests/data/fasta/1ake.fas b/core/tests/data/fasta/1ake.fas
index 024c40b462b71087ab6316084af16b9fed35ed69..6e08a6c407f9c016660376c29376b7ade696d12f 100644
--- a/core/tests/data/fasta/1ake.fas
+++ b/core/tests/data/fasta/1ake.fas
@@ -1,8 +1,8 @@
 > 1AKE.B
 MRIILLGAPGAGKGTQAQFIMEKYGIPQISTGDMLRAAVKSGSELGKQAKDIMDAGKLVTDELVIALVKERIAQEDCRNG
 FLLDGFPRTIPQADAMKEAGINVDYVLEFDVPDELIVDRIVGRRVHAPSGRVYHVKFNPPKVEGKDDVTGEELTTRKDDQ
-EETVRKRLVEYHQMTAPLIGYYSKEAEAGNTKYAKVDGTKPV---AEVRADLEKILG
+EETVRKRLVEYHQMTAPLIGYYYYSKEAEAGNTKYAKVDGTKPV---AEVRADLEKILG
 > target
 -------APGAGKGTQAQFIMEKYGIPQISTGGGLRAAVKS---LGKQAKDIMDAGKLVTDELVIALVKERIAQEDCRNG
 FLLDGFPRTIPQADAMKEAGINVDYVLEF----ELIVDRIVGRRVHAPSGRVYHVKFNPPKVEGKDDVTGEELTTRKDDQ
-EETVRKRLVEYHQMTAPLLYYYYKEAEAGNTKYAKVDGTKPVAEVRADLEKILG---
+EETVRKRLVEYHQMTAPLL--YYYYKEAEAGNTKYAKVDGTKPVAEVRADLEKILG---
diff --git a/core/tests/test_pm3argparse.py b/core/tests/test_pm3argparse.py
index 9b4dff068f6e013ff4a0548b206d41b55420c613..117b32fd3a03941cc0db3f8351d51a627524e218 100644
--- a/core/tests/test_pm3argparse.py
+++ b/core/tests/test_pm3argparse.py
@@ -1,69 +1,244 @@
-import unittest, sys
+import unittest
+import ost
 from promod3.core import pm3argparse
 
-#argparse writes to stdout/ stderr so we need to fetch it
-class _FetchStd(object):
-    def __init__(self):
-        self.buffer = list()
 
-    def write(self, line):
-        self.buffer.append(line.strip())
+class _FetchLog(ost.LogSink):
+    """
+    Capturing output of the OST logger
+    """
+    def __init__(self):
+        ost.LogSink.__init__(self)
+        self.messages = dict()
 
-    def flush(self):
-        pass
+    def LogMessage(self, message, severity):
+        levels = ['ERROR', 'WARNING', 'SCRIPT', 'INFO', 'VERBOSE', 'DEBUG',
+                  'TRACE']
+        level = levels[severity]
+        if not level in self.messages.keys():
+            self.messages[level] = list()
+        self.messages[level].append(message.strip())
 
 class PM3ArgParseTests(unittest.TestCase):
     def setUp(self):
-        self.original_stderr = sys.stderr
-        self.original_stdout = sys.stdout
-        sys.stderr = _FetchStd()
-        sys.stdout = _FetchStd()
+        self.log = _FetchLog()
+        ost.PushLogSink(self.log)
+        ost.PushVerbosityLevel(2)
 
     def tearDown(self):
-        sys.stderr = self.original_stderr
-        sys.stdout = self.original_stdout
+        ost.PopVerbosityLevel()
+        ost.PopLogSink()
 
     def testUnrecognisedArguments(self):
         parser = pm3argparse.PM3ArgumentParser(action=False)
-        with self.assertRaises(SystemExit) as ec:
+        with self.assertRaises(SystemExit) as ecd:
             parser.Parse(['-x'])
-        self.assertEqual(ec.exception.code, 2)
-        self.assertEqual(sys.stderr.buffer, ['usage: test_pm3argparse.py [-h]',
-                                             'test_pm3argparse.py: error: '+
-                                             'unrecognized arguments: -x'])
+        self.assertEqual(ecd.exception.code, 2)
+        self.assertEqual(self.log.messages['ERROR'],
+                         ['usage: test_pm3argparse.py [-h]',
+                          'test_pm3argparse.py: error: unrecognized '+
+                          'arguments: -x'])
 
     def testActionSwitch(self):
         parser = pm3argparse.PM3ArgumentParser(action=False)
-        with self.assertRaises(SystemExit) as ec:
+        with self.assertRaises(SystemExit) as ecd:
             parser.Parse(['--help'])
-        self.assertEqual(ec.exception.code, 0)
-        self.assertEqual(sys.stdout.buffer, ['usage: test_pm3argparse.py '+
-                                             '[-h]\n\noptional arguments:\n  '+
-                                             '-h, --help  show this help '+
-                                             'message and exit'])
+        self.assertEqual(ecd.exception.code, 0)
+        self.assertEqual(self.log.messages['SCRIPT'],
+                         ['usage: test_pm3argparse.py [-h]\n\noptional '+
+                          'arguments:\n  -h, --help  show this help message '+
+                          'and exit'])
 
-        sys.stdout.buffer = list()
+        self.log.messages = dict()
         parser = pm3argparse.PM3ArgumentParser(action=True)
-        with self.assertRaises(SystemExit) as ec:
+        with self.assertRaises(SystemExit) as ecd:
             parser.Parse(['--help'])
-        self.assertEqual(ec.exception.code, 0)
-        self.assertEqual(sys.stdout.buffer, ['usage: t_pm3argparse.py '+
-                                             '[-h]\n\noptional arguments:\n  '+
-                                             '-h, --help  show this help '+
-                                             'message and exit'])
+        self.assertEqual(ecd.exception.code, 0)
+        self.assertEqual(self.log.messages['SCRIPT'],
+                         ['usage: t_pm3argparse.py [-h]\n\noptional '+
+                          'arguments:\n  -h, --help  show this help message '+
+                          'and exit'])
 
 
     def testDescription(self):
         parser = pm3argparse.PM3ArgumentParser(action=False,
                                                description='This is a test.')
-        with self.assertRaises(SystemExit) as ec:
+        with self.assertRaises(SystemExit) as ecd:
             parser.Parse(['--help'])
-        self.assertEqual(ec.exception.code, 0)
-        self.assertEqual(sys.stdout.buffer, ['usage: test_pm3argparse.py '+
-                                             '[-h]\n\nThis is a '+
-                                             'test.\n\noptional arguments:\n  '+
-                                             '-h, --help  show this help '+
-                                             'message and exit'])
+        self.assertEqual(ecd.exception.code, 0)
+        self.assertEqual(self.log.messages['SCRIPT'],
+                         ['usage: test_pm3argparse.py [-h]\n\nThis is a '+
+                          'test.\n\noptional arguments:\n  -h, --help  show '+
+                          'this help message and exit'])
+
+    def testAddAlignemntNoTrgPfx(self):
+        # checking that we fail on missing 'trg:' prefix for arguments of
+        # --fasta
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            parser.Parse(['--fasta', 'foo', 'bar'])
+        self.assertEqual(ecd.exception.code, 11)
+        self.assertEqual(self.log.messages['ERROR'][0],
+                         "'--fasta' requires one "+
+                         "argument prefixed with 'trg:' marking the target "+
+                         "sequence name")
+
+    def testAddAlignemntEmptyTrgPfx(self):
+        # checking that we fail on empty 'trg:' prefix for arguments of
+        # --fasta
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            parser.Parse(['--fasta', 'trg:', 'bar'])
+        self.assertEqual(ecd.exception.code, 14)
+        self.assertEqual(self.log.messages['ERROR'][0], "'--fasta' requires "+
+                         "argument 'trg:' defining the target sequence name, "+
+                         "empty one found: 'trg: bar'")
+
+    def testAddAlignemntSwapTrgPfx(self):
+        # checking that we fail on empty 'trg:' prefix for arguments of
+        # --fasta
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            parser.Parse(['--fasta', 'bar', 'trg:'])
+        self.assertEqual(ecd.exception.code, 14)
+        self.assertEqual(self.log.messages['ERROR'][0], "'--fasta' requires "+
+                         "argument 'trg:' defining the target sequence name, "+
+                         "empty one found: 'bar trg:'")
+
+    def testAddAlignmentNoFile(self):
+        # check that we throw an error if a non-exisiting file is given
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            parser.Parse(['--fasta', 'trg:foo', 'notexistingfile.fas'])
+        self.assertEqual(ecd.exception.code, 12)
+        self.assertEqual(self.log.messages['ERROR'][0],
+                         "Alignment file does not exist: notexistingfile.fas")
+
+    def testAddAlignmentEmpty(self):
+        # we want to fail if we get an empty FastA file
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            parser.Parse(['--fasta', 'trg:foo', 'data/fasta/alignment.fas'])
+        self.assertEqual(ecd.exception.code, 15)
+        self.assertEqual(self.log.messages['ERROR'][0],
+                         "'--fasta' refers to an empty file or its in the "+
+                         "wrong format: data/fasta/alignment.fas")
+
+    def testAddAlignmentToMany(self):
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            parser.Parse(['--fasta', 'trg:target', 'data/fasta/1ake_3.fas'])
+        self.assertEqual(ecd.exception.code, 16)
+        self.assertEqual(self.log.messages['ERROR'][0], "'--fasta trg:target "+
+                         "data/fasta/1ake_3.fas' points to an alignment with "+
+                         "more than 2 sequences.")
+
+    def testAddAlignmentMissingTargetName(self):
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            parser.Parse(['--fasta', 'trg:trg', 'data/fasta/1ake.fas'])
+        self.assertEqual(ecd.exception.code, 17)
+        self.assertEqual(self.log.messages['ERROR'][0], "'--fasta trg:trg "+
+                         "data/fasta/1ake.fas' does not define a target name "+
+                         "found in the alignment.")
+
+    def testAddAlignmentDifferentSeqLens(self):
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        with self.assertRaises(SystemExit) as ecd:
+            parser.Parse(['--fasta', 'trg:target', 'data/fasta/1ake_nel.fas'])
+        self.assertEqual(ecd.exception.code, 18)
+        self.assertEqual(self.log.messages['ERROR'][0], "'--fasta trg:target "+
+                         "data/fasta/1ake_nel.fas': sequences in the "+
+                         "alignment have different length.")
+
+    def testAddAlignmentGzipIn(self):
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        opts = parser.Parse(['--fasta', 'trg:target',
+                             'data/fasta/1ake.fas.gz', '--fasta', 'trg:target',
+                             'data/fasta/1ake.fas'])
+        self.assertEqual(str(opts.alignments[0]), 'target  APGAGKGTQAQFIMEKYG'+
+                         'IPQISTGGGLRAAVKS---LGKQAKDIMDAGKLVTDELVIALVKERIAQED'+
+                         'CRN\n1AKE.B  APGAGKGTQAQFIMEKYGIPQISTGDMLRAAVKSGSEL'+
+                         'GKQAKDIMDAGKLVTDELVIALVKERIAQEDCRN\n\ntarget  GFLLD'+
+                         'GFPRTIPQADAMKEAGINVDYVLEF----ELIVDRIVGRRVHAPSGRVYHV'+
+                         'KFNPPKVEGKDDVTGE\n1AKE.B  GFLLDGFPRTIPQADAMKEAGINVD'+
+                         'YVLEFDVPDELIVDRIVGRRVHAPSGRVYHVKFNPPKVEGKDDVTGE\n\n'+
+                         'target  ELTTRKDDQEETVRKRLVEYHQMTAPLLYYYYKEAEAGNTKYA'+
+                         'KVDGTKPVAEVRADLEKILG\n1AKE.B  ELTTRKDDQEETVRKRLVEYH'+
+                         'QMTAPLIGYYSKEAEAGNTKYAKVDGTKPV---AEVRADLEK\n')
+        self.assertEqual(opts.alignments[0].GetSequence(1).offset, 7)
+        self.assertEqual(str(opts.alignments[1]), 'target  APGAGKGTQAQFIMEKYG'+
+                         'IPQISTGGGLRAAVKS---LGKQAKDIMDAGKLVTDELVIALVKERIAQED'+
+                         'CRN\n1AKE.B  APGAGKGTQAQFIMEKYGIPQISTGDMLRAAVKSGSEL'+
+                         'GKQAKDIMDAGKLVTDELVIALVKERIAQEDCRN\n\ntarget  GFLLD'+
+                         'GFPRTIPQADAMKEAGINVDYVLEF----ELIVDRIVGRRVHAPSGRVYHV'+
+                         'KFNPPKVEGKDDVTGE\n1AKE.B  GFLLDGFPRTIPQADAMKEAGINVD'+
+                         'YVLEFDVPDELIVDRIVGRRVHAPSGRVYHVKFNPPKVEGKDDVTGE\n\n'+
+                         'target  ELTTRKDDQEETVRKRLVEYHQMTAPLL--YYYYKEAEAGNTK'+
+                         'YAKVDGTKPVAEVRADLEKILG\n1AKE.B  ELTTRKDDQEETVRKRLVE'+
+                         'YHQMTAPLIGYYYYSKEAEAGNTKYAKVDGTKPV---AEVRADLEK\n')
+
+    def testAddAlignmentSwitchSeqs(self):
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        opts = parser.Parse(['--fasta', 'trg:target',
+                             'data/fasta/1ake.fas'])
+        self.assertEqual(str(opts.alignments[0].GetSequence(0)),
+                         'APGAGKGTQAQFIMEKYGIPQISTGGGLRAAVKS---LGKQAKDIMDAGK'+
+                         'LVTDELVIALVKERIAQEDCRNGFLLDGFPRTIPQADAMKEAGINVDYVL'+
+                         'EF----ELIVDRIVGRRVHAPSGRVYHVKFNPPKVEGKDDVTGEELTTRK'+
+                         'DDQEETVRKRLVEYHQMTAPLL--YYYYKEAEAGNTKYAKVDGTKPVAEV'+
+                         'RADLEKILG')
+
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        opts = parser.Parse(['--fasta', 'trg:target',
+                             'data/fasta/1ake_sw.fas'])
+        self.assertEqual(str(opts.alignments[0].GetSequence(0)),
+                         'APGAGKGTQAQFIMEKYGIPQISTGGGLRAAVKS---LGKQAKDIMDAGK'+
+                         'LVTDELVIALVKERIAQEDCRNGFLLDGFPRTIPQADAMKEAGINVDYVL'+
+                         'EF----ELIVDRIVGRRVHAPSGRVYHVKFNPPKVEGKDDVTGEELTTRK'+
+                         'DDQEETVRKRLVEYHQMTAPLL--YYYYKEAEAGNTKYAKVDGTKPVAEV'+
+                         'RADLEKILG')
+
+    def testAddAlignment(self):
+        parser = pm3argparse.PM3ArgumentParser(action=False)
+        parser.AddAlignment()
+        parser.AssembleParser()
+        opts = parser.Parse(['--fasta', 'trg:target',
+                             'data/fasta/1ake.fas'])
+        self.assertEqual(len(opts.alignments), 1)
+        self.assertEqual(opts.alignments[0].GetLength(), 209)
+        self.assertEqual(opts.alignments[0].GetSequenceOffset(0), 0)
+        self.assertEqual(opts.alignments[0].GetSequenceOffset(1), 7)
+        self.assertEqual(opts.alignments[0].GetSequence(0).gapless_string,
+                         'APGAGKGTQAQFIMEKYGIPQISTGGGLRAAVKSLGKQAKDIMDAGKLVT'+
+                         'DELVIALVKERIAQEDCRNGFLLDGFPRTIPQADAMKEAGINVDYVLEFE'+
+                         'LIVDRIVGRRVHAPSGRVYHVKFNPPKVEGKDDVTGEELTTRKDDQEETV'+
+                         'RKRLVEYHQMTAPLLYYYYKEAEAGNTKYAKVDGTKPVAEVRADLEKILG')
+        self.assertEqual(opts.alignments[0].GetSequence(0).name, 'target')
+        self.assertEqual(opts.alignments[0].GetSequence(1).name, '1AKE.B')
+        self.assertEqual(opts.aln_sources[0], 'data/fasta/1ake.fas')
 
 if __name__ == "__main__":
     from ost import testutils
diff --git a/extras/pre_commit/pm3_csc/filecheck/pylintrc b/extras/pre_commit/pm3_csc/filecheck/pylintrc
index 66347b07c03d811f78ebcd2f93b44d80de13dc73..b9244937e453b7f8865f36d5e7778372b66c1fd5 100644
--- a/extras/pre_commit/pm3_csc/filecheck/pylintrc
+++ b/extras/pre_commit/pm3_csc/filecheck/pylintrc
@@ -290,7 +290,7 @@ max-attributes=7
 min-public-methods=2
 
 # Maximum number of public methods for a class (see R0904).
-max-public-methods=20
+max-public-methods=21
 
 
 [IMPORTS]