changeset 35:9845c649f41b draft

planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/cutadapt commit c37e2aeba811fd041c08f0e119a3cbe90bfa7418
author iuc
date Sun, 17 Dec 2023 18:52:25 +0000
parents 8c0175e03cee
children 64172f1c1202
files cutadapt.xml macros.xml test-data/cutadapt/cut/illumina64.fastq test-data/cutadapt/cut/maxee.fastq test-data/cutadapt/cut/polya.1.fasta test-data/cutadapt/cut/polya.2.fasta test-data/cutadapt/cut/polya.legacy.1.fasta test-data/cutadapt/cut/simple.fasta test-data/cutadapt/cut/simple.fasta.gz test-data/cutadapt/cut/wildcard.fa test-data/cutadapt/cut/wildcardN.fa test-data/cutadapt/data/illumina64.fastq test-data/cutadapt/data/maxee.fastq test-data/cutadapt/data/polya.1.fasta test-data/cutadapt/data/polya.2.fasta test-data/cutadapt/data/simple.fasta test-data/cutadapt/data/simple.fasta.gz test-data/cutadapt/data/wildcard.fa test-data/cutadapt/data/wildcardN.fa test-data/cutadapt_rest.json
diffstat 20 files changed, 652 insertions(+), 379 deletions(-) [+]
line wrap: on
line diff
--- a/cutadapt.xml	Fri May 19 21:42:14 2023 +0000
+++ b/cutadapt.xml	Sun Dec 17 18:52:25 2023 +0000
@@ -39,15 +39,18 @@
     #set read1 = re.sub('[^\w\-\s]', '_', str($library.input_1.element_identifier))
 #end if
 
-#if $input_1.is_of_type("fastq.gz", "fastqsanger.gz"):
-    #set ext = ".fq.gz"
-#else if $input_1.is_of_type("fastq.bz2", "fastqsanger.bz2"):
-    #set ext = ".fq.bz2"
-#else if $input_1.is_of_type('fasta'):
+#if $input_1.is_of_type("fastq"):
+    #set ext = ".fq"
+#else
     #set ext = ".fa"
-#else:
-    #set ext = ".fq"
 #end if
+#if $input_1.ext.endswith(".gz"):
+    #set ext=ext+".gz"
+#elif $input_1.ext.endswith(".bz2")
+    #set ext=ext+".bz2"
+#end if
+
+
 #set read1 = $read1 + $ext
 #set out1 = "out1" + $ext
 #set rest_output = "rest_output" + $ext
@@ -86,7 +89,7 @@
 -j=\${GALAXY_SLOTS:-4}
 
 #if 'json_stats' in $output_selector:
-        --json stats.json
+    --json stats.json
 #end if
 
 #if str( $library.type ) == "single":
@@ -108,19 +111,20 @@
 --overlap=$adapter_options.overlap
 $adapter_options.no_indels
 $adapter_options.match_read_wildcards
+$adapter_options.no_match_adapter_wildcards
 --action=$adapter_options.action
 $adapter_options.revcomp
 
 $filter_options.discard_trimmed
 $filter_options.discard_untrimmed
 
-#if str($filter_options.minimum_length) and str($filter_options.length_R2_options.length_R2_status) == 'True':
-    --minimum-length=$filter_options.minimum_length:$filter_options.length_R2_options.R2_minimum
+#if str($filter_options.minimum_length) and str($library.type) != "single" and str($library.minimum_length2) != '':
+    --minimum-length=$filter_options.minimum_length:$library.minimum_length2
 #else if str($filter_options.minimum_length):
     --minimum-length=$filter_options.minimum_length
 #end if
-#if str($filter_options.maximum_length) and str($filter_options.length_R2_options.length_R2_status) == 'True':
-    --maximum-length=$filter_options.maximum_length:$filter_options.length_R2_options.R2_maximum
+#if str($filter_options.maximum_length) and str($library.type) != "single" and str($library.maximum_length2) != '':
+    --maximum-length=$filter_options.maximum_length:$library.maximum_length2
 #else if str($filter_options.maximum_length):
     --maximum-length=$filter_options.maximum_length
 #end if
@@ -137,6 +141,10 @@
 #end if
 $filter_options.discard_cassava
 
+#if $input_1.ext.startswith("fastqillumina") or $input_1.ext.startswith("fastqsolexa")
+    --quality-base=64
+#end if
+
 #if str($read_mod_options.quality_cutoff) != '0':
    --quality-cutoff=$read_mod_options.quality_cutoff
 #end if
@@ -144,6 +152,7 @@
     --nextseq-trim=$read_mod_options.nextseq_trim
 #end if
 $read_mod_options.trim_n
+$read_mod_options.poly_a
 #if $read_mod_options.strip_suffix != ''
     --strip-suffix $read_mod_options.strip_suffix
 #end if
@@ -206,72 +215,56 @@
         <!-- Adapter Options -->
         <section name="adapter_options" title="Adapter Options">
             <param name="action" type="select" label="What to do if a match is found">
-                <option value="trim" selected="True">Trim: trim adapter and upstream or downstream sequence</option>
+                <option value="trim" selected="true">Trim: trim adapter and upstream or downstream sequence</option>
                 <option value="retain">Retain: the read is trimmed, but the adapter sequence is not removed</option>
                 <option value="mask">Mask: mask adapters with 'N' characters instead of trimming them</option>
                 <option value="lowercase">Lowercase: convert to lowercase</option>
                 <option value="none">None: leave unchanged</option>
             </param>
-            <param name="internal" type="select" label="Disallow internal adaptor ocurrences" help="The non-internal 5’ and 3’ adapter types disallow internal occurrences of the adapter sequence. The adapter must always be at one of the ends of the read, but partial occurrences are also ok.">
-                <option value="X">Enabled</option>
-                <option value="" selected="True">Disabled</option>
-            </param>
             <param argument="--error-rate" type="float" min="0" max="1" value="0.1" label="Maximum error rate" help="Maximum allowed error rate (no. of errors divided by the length of the matching region)." />
-            <param argument="--no-indels" type="boolean" value="False" truevalue="--no-indels" falsevalue="" label="Do not allow indels (Use ONLY with anchored 5' (front) adapters)." help="Do not allow indels in the alignments. That is, allow only mismatches. This option is currently only supported for anchored 5' adapters ('^ADAPTER') (default: both mismatches and indels are allowed)." />
+            <param argument="--no-indels" type="boolean" checked="false" truevalue="--no-indels" falsevalue="" label="Do not allow indels (Use ONLY with anchored 5' (front) adapters)." help="Do not allow indels in the alignments. That is, allow only mismatches. This option is currently only supported for anchored 5' adapters ('^ADAPTER') (default: both mismatches and indels are allowed)." />
             <param argument="--times" type="integer" min="1" value="1" label="Match times" help="Try to remove adapters at most COUNT times. Useful when an adapter gets appended multiple times." />
             <param argument="--overlap" type="integer" min="1" value="3" label="Minimum overlap length" help="Minimum overlap length. If the overlap between the adapter and the sequence is shorter than LENGTH, the read is not modified. This reduces the number of bases trimmed purely due to short random adapter matches." />
-                <param name="match_read_wildcards" type="select"  label="Match wildcards" help="Allow 'N's as matches. Default: in the adapters but not in the reads">
-                <option value=" " selected="True">In the adapters but not in the reads</option>
-                <option value="--match-read-wildcards">In the adapters and in the reads</option>
-                <option value="--no-match-adapter-wildcards">Nowhere</option>
-            </param>
-            <param argument="--revcomp" type="boolean" value="False" truevalue="--revcomp" falsevalue="" label="Look for adapters in the reverse complement" help="Check both the read and its reverse complement for adapter matches. If match is on reverse-complemented version, output that one. Default: check only read." />
+            <param argument="--match-read-wildcards" type="boolean" checked="false" truevalue="--match-read-wildcards" falsevalue="" label="Match wilcards in reads" help="Interpret IUPAC wildcards in reads"/>
+            <param argument="--no-match-adapter-wildcards" type="boolean" checked="true" truevalue="" falsevalue="--no-match-adapter-wildcards" label="Match wilcards in adapters" help="Interpret IUPAC wildcards in adapters."/>
+            <param argument="--revcomp" type="boolean" checked="false" truevalue="--revcomp" falsevalue="" label="Look for adapters in the reverse complement" help="Check both the read and its reverse complement for adapter matches. If match is on reverse-complemented version, output that one. Default: check only read." />
         </section>
 
         <!-- Filter Options -->
         <section name="filter_options" title="Filter Options">
-            <param argument="--discard-trimmed" type="boolean" value="False" truevalue="--discard-trimmed" falsevalue="" label="Discard Trimmed Reads" help="Discard reads that contain the adapter instead of trimming them. Use the 'Minimum overlap length' option in order to avoid throwing away too many randomly matching reads!" />
-            <param argument="--discard_untrimmed" type="boolean" value="False" truevalue="--discard-untrimmed" falsevalue="" label="Discard Untrimmed Reads" help="Discard reads that do not contain the adapter." />
-            <param argument="--minimum-length" type="integer" min="0" optional="True" value="" label="Minimum length (R1)" help="Discard trimmed reads that are shorter than LENGTH.  Reads that are too short even before adapter removal are also discarded." />
-            <param argument="--maximum-length" type="integer" min="0" optional="True" value="" label="Maximum length (R1)" help="Discard trimmed reads that are longer than LENGTH.  Reads that are too long even before adapter removal are also discarded." />
-            <conditional name="length_R2_options">
-                <param name="length_R2_status" type="select" label="Specify a minimum/maximum length for reverse reads (R2)" help="When trimming paired-end reads, the minimum/maximum lengths for R1 and R2 can be specified separately. If not provided, the same minimum length applies to both reads.">
-                    <option value="True">Enabled</option>
-                    <option value="False" selected="True">Disabled</option>
-                </param>
-                <when value="True">
-                    <param name="R2_minimum" type="integer" min="0" value="" optional="True" label="Minimum length (R2)" />
-                    <param name="R2_maximum" type="integer" min="0" value="" optional="True" label="Maximum length (R2)" />
-                </when>
-                <when value="False">
-                </when>
-            </conditional>
-            <param argument="--max-n" type="float" min="0" optional="True" label="Max N" help="Discard reads with more than this number of 'N' bases. A number between 0 and 1 is interpreted as a fraction of the read length." />
-            <param argument="--pair-filter" type="select" optional="True" label="Pair filter" help="Which of the reads in a paired-end read have to match the filtering criterion in order for the pair to be filtered. Default: any">
-                <option value="any" selected="True">Any: a read pair is discarded (or redirected) if one of the reads (R1 or R2) fulfills the filtering criterion. </option>
+            <param argument="--discard-trimmed" type="boolean" checked="false" truevalue="--discard-trimmed" falsevalue="" label="Discard Trimmed Reads" help="Discard reads that contain the adapter instead of trimming them. Use the 'Minimum overlap length' option in order to avoid throwing away too many randomly matching reads!" />
+            <param argument="--discard_untrimmed" type="boolean" checked="false" truevalue="--discard-untrimmed" falsevalue="" label="Discard Untrimmed Reads" help="Discard reads that do not contain the adapter." />
+            <param argument="--minimum-length" type="integer" min="0" optional="true" value="" label="Minimum length (R1)" help="Discard trimmed reads that are shorter than LENGTH.  Reads that are too short even before adapter removal are also discarded." />
+            <param argument="--maximum-length" type="integer" min="0" optional="true" value="" label="Maximum length (R1)" help="Discard trimmed reads that are longer than LENGTH.  Reads that are too long even before adapter removal are also discarded." />
+            <param argument="--max-n" type="float" min="0" optional="true" label="Max N" help="Discard reads with more than this number of 'N' bases. A number between 0 and 1 is interpreted as a fraction of the read length." />
+            <param argument="--pair-filter" type="select" optional="true" label="Pair filter" help="Which of the reads in a paired-end read have to match the filtering criterion in order for the pair to be filtered. Default: any">
+                <option value="any" selected="true">Any: a read pair is discarded (or redirected) if one of the reads (R1 or R2) fulfills the filtering criterion. </option>
                 <option value="both">Both: filtering criteria must apply to both reads in order for a read pair to be discarded. </option>
                 <option value="first">First: will make a decision about the read pair by inspecting whether the filtering criterion applies to the first read, ignoring the second read.</option>
 
             </param>
-            <param argument="--max-expected-errors" type="integer" min="0" optional="True" value="" label="Max expected errors" help="Discard reads whose expected number of errors (computed from quality values) exceeds this value." />
-            <param argument="--discard-cassava" type="boolean" truevalue="--discard-cassava" falsevalue="" checked="False" label="Discard CASAVA filtering" help="Discard reads that did not pass CASAVA filtering (header has :Y:)." />
+            <param argument="--max-expected-errors" type="float" min="0" optional="true" value="" label="Max expected errors" help="Discard reads whose expected number of errors (computed from quality values) exceeds this value." />
+            <param argument="--max-average-error-rate" type="float" min="0" max="1" optional="true" value="" label="Max average expected errors" help="As --max-expected-errors (see above), but divided by length to account for reads of varying length" />
+            <param argument="--discard-cassava" type="boolean" truevalue="--discard-cassava" falsevalue="" checked="false" label="Discard CASAVA filtering" help="Discard reads that did not pass CASAVA filtering (header has :Y:)." />
         </section>
 
         <!-- Read Modification Options -->
         <section name="read_mod_options" title="Read Modification Options">
+            <param argument="--cut" type="integer" value="0" optional="true" label="Cut bases from reads before adapter trimming" help="Remove bases from each read (first read only if paired). If positive, remove bases from the beginning. If negative, remove bases from the end. This is applied *before* adapter trimming." />
             <param argument="--quality-cutoff" type="text" value="0" label="Quality cutoff" help=" Trim low-quality bases from 5' and/or 3' ends of each read before adapter removal. Applied to both reads for paired-end data, unless a separate value for the second read is specified. If one value is given, only the 3' end is trimmed. If two comma-separated cutoffs are given, the 5' end is trimmed with the first cutoff, the 3' end with the second.">
                 <sanitizer>
                     <valid initial="string.digits"><add value="," /></valid>
                 </sanitizer>
-                <validator type="regex">[0-9,]+</validator>
+                <validator type="regex">[0-9]+(,[0-9])?</validator>
             </param>
             <param argument="--nextseq-trim" type="integer" value="0" label="NextSeq trimming" help="Experimental option for quality trimming of NextSeq data. This is necessary because that machine cannot distinguish between G and reaching the end of the fragment (it encodes G as ‘black’). This option works like regular quality trimming (where one would use -q 20 instead), except that the qualities of G bases are ignored." />
-            <param argument="--trim-n" type="boolean" truevalue="--trim-n" falsevalue="" checked="False" label="Trim Ns" help="Trim N's on ends of reads." />
+            <param argument="--trim-n" type="boolean" truevalue="--trim-n" falsevalue="" checked="false" label="Trim Ns" help="Trim N's on ends of reads." />
+            <param argument="--poly-a" type="boolean" truevalue="--poly-a" falsevalue="" checked="false" label="Trim poly-A tails" help="Note, this trim poly-T 'heads' on R2"/>
             <param argument="--strip-suffix" label="Strip suffix" type="text" help="Remove this suffix from read names if present." />
             <conditional name="shorten_options">
                 <param name="shorten_values" type="select" label="Shortening reads to a fixed length" help="If you want to remove a fixed number of bases from each read, use the –cut option instead.">
                     <option value="True">Enabled</option>
-                    <option value="False" selected="True">Disabled</option>
+                    <option value="False" selected="true">Disabled</option>
                 </param>
                 <when value="True">
                     <param argument="--length" type="integer" value="0" label="Length" help="Shorten reads to this length. This modification is applied after adapter trimming." />
@@ -283,7 +276,7 @@
                 <when value="False">
                 </when>
             </conditional>
-            <param argument="--length-tag" label="Length tag" type="text" optional="True" help="Search for TAG followed by a decimal number in the name of the read (description/comment field of the FASTA or FASTQ file). Replace the decimal number with the correct length of the trimmed read. For example, use --length-tag 'length=' to search for fields like 'length=123'." >
+            <param argument="--length-tag" label="Length tag" type="text" optional="true" help="Search for TAG followed by a decimal number in the name of the read (description/comment field of the FASTA or FASTQ file). Replace the decimal number with the correct length of the trimmed read. For example, use --length-tag 'length=' to search for fields like 'length=123'." >
                 <sanitizer invalid_char="">
                     <valid initial="string.letters,string.digits">
                         <add value="/" />
@@ -296,7 +289,7 @@
                 </sanitizer>
                 <validator type="regex">[A-Za-z0-9 =-_/+]+</validator>
             </param>
-            <param argument="--rename" label="Rename reads" type="text" optional="True" help="This option can be used to rename both single-end and paired-end reads. ">
+            <param argument="--rename" label="Rename reads" type="text" optional="true" help="This option can be used to rename both single-end and paired-end reads. ">
                 <sanitizer invalid_char="">
                     <valid initial="string.letters,string.digits">
                         <add value="{" />
@@ -308,11 +301,11 @@
                 </sanitizer>
                 <validator type="regex">[A-Za-z0-9 {}=_]+</validator>
             </param>
-            <param argument="--zero-cap" type="boolean" truevalue="--zero-cap" falsevalue="" checked="False" label="Change negative quality values to zero" />
+            <param argument="--zero-cap" type="boolean" truevalue="--zero-cap" falsevalue="" checked="false" label="Change negative quality values to zero" />
         </section>
 
         <!-- Output Options -->
-        <param name="output_selector" type="select" multiple="True" display="checkboxes" label="Outputs selector">
+        <param name="output_selector" type="select" multiple="true" display="checkboxes" label="Outputs selector">
             <option value="report">Report: Cutadapt's per-adapter statistics. You can use this file with MultiQC.</option>
             <option value="info_file">Info file: write information about each read and its adapter matches.</option>
             <option value="rest_file">Rest of read: when the adapter matches in the middle of a read, write the rest (after the adapter).</option>
@@ -326,20 +319,20 @@
     </inputs>
 
     <outputs>
-        <data name="out1" format="fastqsanger" metadata_source="input_1" from_work_dir="out1*" label="${tool.name} on ${on_string}: Read 1 Output">
+        <data name="out1" format="fastqsanger" metadata_source="input_1" from_work_dir="out1.*" label="${tool.name} on ${on_string}: Read 1 Output">
             <filter>library['type'] != 'paired_collection' and 'multiple_output' not in output_selector</filter>
             <expand macro="inherit_format_1" />
         </data>
 
-        <data name="out2" format="fastqsanger" metadata_source="input_2" from_work_dir="out2*" label="${tool.name} on ${on_string}: Read 2 Output" >
+        <data name="out2" format="fastqsanger" metadata_source="input_2" from_work_dir="out2.*" label="${tool.name} on ${on_string}: Read 2 Output" >
             <filter>library['type'] == 'paired' and 'multiple_output' not in output_selector</filter>
             <expand macro="inherit_format_2" />
         </data>
 
         <collection name="out_pairs" type="paired" format_source="input_1" label="${tool.name} on ${on_string}: Reads">
             <filter>library['type'] == 'paired_collection' and 'multiple_output' not in output_selector</filter>
-            <data name="forward" from_work_dir="out1.fq*" />
-            <data name="reverse" from_work_dir="out2.fq*" />
+            <data name="forward" from_work_dir="out1.*" />
+            <data name="reverse" from_work_dir="out2.*" />
         </collection>
         
         <data name="report" format="txt" from_work_dir="report.txt" label="${tool.name} on ${on_string}: Report">
@@ -422,7 +415,7 @@
                     </conditional>
                 </repeat>
             </section>
-            <output name="out1" decompress="True" file="cutadapt_out1.fq.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_out1.fq.gz" ftype="fastq.gz"/>
         </test>
         <!-- Ensure paired end fastq.gz works -->
         <test expect_num_outputs="2">
@@ -439,14 +432,14 @@
             </section>
             <section name="r2">
                 <repeat name="adapters2">
-                    <conditional name="adapter_source2">
-                        <param name="adapter_source_list2" value="user"/>
-                        <param name="adapter2" value="AGATCGGAAGAGC"/>
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
             </section>
-            <output name="out1" decompress="True" file="cutadapt_out1.fq.gz" ftype="fastq.gz"/>
-            <output name="out2" decompress="True" file="cutadapt_out2.fq.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_out1.fq.gz" ftype="fastq.gz"/>
+            <output name="out2" decompress="true" file="cutadapt_out2.fq.gz" ftype="fastq.gz"/>
             <assert_command>
                 <not_has_text text="--discard-trimmed"/>
                 <not_has_text text="--discard-untrimmed"/>
@@ -475,23 +468,15 @@
             </section>
             <section name="r2">
                 <repeat name="adapters2">
-                    <conditional name="adapter_source2">
-                        <param name="adapter_source_list2" value="user"/>
-                        <param name="adapter2" value="AGATCGGAAGAGC"/>
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
             </section>
             <output_collection name="out_pairs" type="paired" count="2">
-                <element name="forward" decompress="true" file="cutadapt_out1.fq.gz" ftype="fastq.gz">
-                    <assert_contents>
-                        <has_size value="12000" delta="2000" />
-                    </assert_contents>
-                </element>
-                <element name="reverse" decompress="true" file="cutadapt_out2.fq.gz" ftype="fastq.gz">
-                    <assert_contents>
-                        <has_size value="12000" delta="2000" />
-                    </assert_contents>
-                </element>
+                <element name="forward" decompress="true" file="cutadapt_out1.fq.gz" ftype="fastq.gz"/>
+                <element name="reverse" decompress="true" file="cutadapt_out2.fq.gz" ftype="fastq.gz"/>
             </output_collection>
         </test>
         <!-- Ensure built-in adapters work -->
@@ -520,7 +505,7 @@
                 </repeat>
             </section>
             <section name="filter_options">
-                <param name="discard_trimmed" value="True"/>
+                <param name="discard_trimmed" value="true"/>
             </section>
             <output name="out1" file="cutadapt_discard.out" ftype="fastq"/>
             <assert_command>
@@ -540,8 +525,8 @@
             </section>
             <param name="output_selector" value="rest_file,json_stats"/>
             <output name="out1" file="cutadapt_rest.out" ftype="fasta"/>
-            <!--allow for differing cutadapt and python version as well as two lines containing the number of cores -->
-            <output name="json_stats" file="cutadapt_rest.json" ftype="json" lines_diff="8"/>
+            <!--allow for differing schema, cutadapt and python version as well as two lines containing the number of cores -->
+            <output name="json_stats" file="cutadapt_rest.json" ftype="json" lines_diff="10"/>
             <output name="rest_output" file="cutadapt_rest2.out" ftype="fasta"/>
         </test>
         <!-- Ensure nextseq-trim option works -->
@@ -557,7 +542,7 @@
                 </repeat>
             </section>
             <param name="nextseq_trim" value="20" />
-            <output name="out1" decompress="True" file="cutadapt_nextseq_out.fq.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_nextseq_out.fq.gz" ftype="fastq.gz"/>
         </test>
         <!-- Ensure Report and Info file output work -->
         <test expect_num_outputs="3">
@@ -588,17 +573,17 @@
                 <param name="input_1" ftype="fastq" value="cutadapt_in_split.fastq" />
                 <section name="r1" >
                     <repeat name="front_adapters">
-                        <conditional name="front_adapter_source">
-                            <param name="front_adapter_source_list" value="user"/>
-                            <param name="front_adapter_name" value="A1" />
-                            <param name="front_adapter" value="^GTCGGTAA" />
+                        <conditional name="adapter_source">
+                            <param name="adapter_source_list" value="user"/>
+                            <param name="adapter_name" value="A1" />
+                            <param name="adapter" value="^GTCGGTAA" />
                         </conditional>
                     </repeat>
                     <repeat name="front_adapters">
-                        <conditional name="front_adapter_source">
-                            <param name="front_adapter_source_list" value="user"/>
-                            <param name="front_adapter_name" value="A2" />
-                            <param name="front_adapter" value="^AGGTCACT" />
+                        <conditional name="adapter_source">
+                            <param name="adapter_source_list" value="user"/>
+                            <param name="adapter_name" value="A2" />
+                            <param name="adapter" value="^AGGTCACT" />
                         </conditional>
                     </repeat>
                 </section>
@@ -620,21 +605,18 @@
                 <param name="input_1" ftype="fastq.gz" value="cutadapt_in_split.fastq.gz" />
                 <section name="r1" >
                     <repeat name="front_adapters">
-                        <conditional name="front_adapter_source">
-                            <param name="front_adapter_source_list" value="file"/>
-                            <param name="front_adapter_file" ftype="fasta"  value="barcodes.fasta" />
+                        <conditional name="adapter_source">
+                            <param name="adapter_source_list" value="file"/>
+                            <param name="adapter_file" ftype="fasta"  value="barcodes.fasta" />
                         </conditional>
                     </repeat>
                 </section>
             </conditional>
             <param name="output_selector" value="multiple_output" />
             <output_collection name="split_output" type="list" count="3">
-                   <element name="A1"  decompress="True" file="A1.fastq.gz" ftype="fastq.gz">
-                   </element>
-                   <element name="A2" decompress="True" file="A2.fastq.gz" ftype="fastq.gz">
-                   </element>
-                   <element name="unknown" decompress="True" file="unknown.fastq.gz" ftype="fastq.gz">
-                   </element>
+                   <element name="A1"  decompress="true" file="A1.fastq.gz" ftype="fastq.gz"/>
+                   <element name="A2" decompress="true" file="A2.fastq.gz" ftype="fastq.gz"/>
+                   <element name="unknown" decompress="true" file="unknown.fastq.gz" ftype="fastq.gz"/>
              </output_collection>
         </test>
 
@@ -667,7 +649,7 @@
                 </repeat>
             </section>
             <param name="output_selector" value="untrimmed_file" />
-            <output name="out1" decompress="True" file="cutadapt_trimmed.out.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_trimmed.out.gz" ftype="fastq.gz"/>
             <!--
                 Do not use the decompress option for this assertion, since it does NOT test that the file is compressed
                 See discussion at https://github.com/galaxyproject/galaxy/issues/7671
@@ -692,8 +674,8 @@
             <section name="r2">
                 <repeat name="adapters">
                     <conditional name="adapter_source">
-                        <param name="adapter_source_list2" value="user"/>
-                        <param name="adapter2" value="AGATCGGAAGAGC"/>
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
             </section>
@@ -722,8 +704,8 @@
                         <param name="adapter" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
-                <param name="cut" value="5"/>
             </section>
+            <param name="cut" value="5"/>
             <output name="out1" file="cutadapt_small_cut.out" ftype="fastq"/>
         </test>
         <!-- Test rename options -->
@@ -737,8 +719,8 @@
                         <param name="adapter" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
-                <param name="cut" value="5"/>
             </section>
+            <param name="cut" value="5"/>
             <section name="read_mod_options">
                 <param name="rename" value="{id} barcode={cut_prefix}"/>
             </section>
@@ -845,22 +827,19 @@
             </section>
             <section name="r2">
                 <repeat name="adapters2">
-                    <conditional name="adapter_source2">
-                        <param name="adapter_source_list2" value="user"/>
-                        <param name="adapter2" value="CTACAAG"/>
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="CTACAAG"/>
                     </conditional>
                 </repeat>
+                <param name="minimum_length2" value="10"/>
             </section>
             <section name="filter_options">
                 <param name="minimum_length" value="30"/>
                 <param name="pair_filter" value="both"/>
-                <conditional name="length_R2_options">
-                    <param name="length_R2_status" value="True"/>
-                    <param name="R2_minimum" value="10"/>
-                </conditional>
             </section>
-            <output name="out1" decompress="True" file="cutadapt_out1_min_length.fq.gz" ftype="fastq.gz"/>
-            <output name="out2" decompress="True" file="cutadapt_out2_min_length.fq.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_out1_min_length.fq.gz" ftype="fastq.gz"/>
+            <output name="out2" decompress="true" file="cutadapt_out2_min_length.fq.gz" ftype="fastq.gz"/>
             <assert_command>
                 <has_text text="--minimum-length=30:10"/>
                 <has_text text="--pair-filter=both"/>
@@ -881,22 +860,19 @@
             </section>
             <section name="r2">
                 <repeat name="adapters2">
-                    <conditional name="adapter_source2">
-                        <param name="adapter_source_list2" value="user"/>
-                        <param name="adapter2" value="AGATCGGAAGAGC"/>
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
+                <param name="maximum_length2" value="30"/>
             </section>
             <section name="filter_options">
                 <param name="pair_filter" value="both"/>
                 <param name="maximum_length" value="50"/>
-                <conditional name="length_R2_options">
-                    <param name="length_R2_status" value="True"/>
-                    <param name="R2_maximum" value="30"/>
-                </conditional>
             </section>
-            <output name="out1" decompress="True" file="cutadapt_out1_max_length.fq.gz" ftype="fastq.gz"/>
-            <output name="out2" decompress="True" file="cutadapt_out2_max_length.fq.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_out1_max_length.fq.gz" ftype="fastq.gz"/>
+            <output name="out2" decompress="true" file="cutadapt_out2_max_length.fq.gz" ftype="fastq.gz"/>
             <assert_command>
                 <has_text text="--maximum-length=50:30"/>
                 <has_text text="--pair-filter=both"/>
@@ -922,20 +898,17 @@
                         <param name="adapter2" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
+                <param name="maximum_length2" value="30"/>
             </section>
             <section name="filter_options">
                 <param name="pair_filter" value="both"/>
                 <param name="minimum_length" value="10"/>
                 <param name="maximum_length" value="50"/>
-                <conditional name="length_R2_options">
-                    <param name="length_R2_status" value="True"/>
-                    <param name="R2_maximum" value="30"/>
-                </conditional>
             </section>
-            <output name="out1" decompress="True" file="cutadapt_out1_max_min_01.fq.gz" ftype="fastq.gz"/>
-            <output name="out2" decompress="True" file="cutadapt_out2_max_min_01.fq.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_out1_max_min_01.fq.gz" ftype="fastq.gz"/>
+            <output name="out2" decompress="true" file="cutadapt_out2_max_min_01.fq.gz" ftype="fastq.gz"/>
             <assert_command>
-                <has_text text="--minimum-length=10:"/>
+                <has_text text="--minimum-length=10"/>
                 <has_text text="--maximum-length=50:30"/>
                 <has_text text="--pair-filter=both"/>
             </assert_command>
@@ -959,21 +932,18 @@
                         <param name="adapter2" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
+                <param name="minimum_length2" value="10"/>
             </section>
             <section name="filter_options">
                 <param name="pair_filter" value="both"/>
                 <param name="minimum_length" value="10"/>
                 <param name="maximum_length" value="50"/>
-                <conditional name="length_R2_options">
-                    <param name="length_R2_status" value="True"/>
-                    <param name="R2_minimum" value="10"/>
-                </conditional>
             </section>
-            <output name="out1" decompress="True" file="cutadapt_out1_max_min_02.fq.gz" ftype="fastq.gz"/>
-            <output name="out2" decompress="True" file="cutadapt_out2_max_min_02.fq.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_out1_max_min_02.fq.gz" ftype="fastq.gz"/>
+            <output name="out2" decompress="true" file="cutadapt_out2_max_min_02.fq.gz" ftype="fastq.gz"/>
             <assert_command>
                 <has_text text="--minimum-length=10:10"/>
-                <has_text text="--maximum-length=50:"/>
+                <has_text text="--maximum-length=50"/>
                 <has_text text="--pair-filter=both"/>
             </assert_command>
         </test>
@@ -1035,6 +1005,7 @@
             </section>
             <output name="out1" file="cutadapt_shorten_expected_errors.out" ftype="fastq"/>
         </test>
+
         <!-- Test disallow internal adaptors option -->
         <test expect_num_outputs="1">
             <param name="type" value="single" />
@@ -1043,13 +1014,10 @@
                 <repeat name="adapters">
                     <conditional name="adapter_source">
                         <param name="adapter_source_list" value="user"/>
-                        <param name="adapter" value="GAANTAGCTACCAC"/>
+                        <param name="adapter" value="GAANTAGCTACCACX"/>
                     </conditional>
                 </repeat>
             </section>
-            <section name="adapter_options">
-                <param name="internal" value="X"/>
-            </section>
             <output name="out1" file="cutadapt_shorten_internal_adapters.out" ftype="fastq"/>
             <assert_command>
                 <has_text text="GAANTAGCTACCACX"/>
@@ -1063,25 +1031,22 @@
                 <repeat name="adapters">
                     <conditional name="adapter_source">
                         <param name="adapter_source_list" value="user"/>
-                        <param name="adapter" value="AGATCGGAAGAGC"/>
+                        <param name="adapter" value="AGATCGGAAGAGCX"/>
                     </conditional>
                 </repeat>
             </section>
             <section name="r2">
                 <repeat name="adapters2">
-                    <conditional name="adapter_source2">
-                        <param name="adapter_source_list2" value="user"/>
-                        <param name="adapter2" value="AGATCGGAAGAGC"/>
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="AGATCGGAAGAGCX"/>
                     </conditional>
                 </repeat>
             </section>
-            <section name="adapter_options">
-                <param name="internal" value="X"/>
-            </section>
-            <output name="out1" decompress="True" file="cutadapt_out1_internal_adapter.fq.gz" ftype="fastq.gz"/>
-            <output name="out2" decompress="True" file="cutadapt_out2_internal_adapter.fq.gz" ftype="fastq.gz"/>
+            <output name="out1" decompress="true" file="cutadapt_out1_internal_adapter.fq.gz" ftype="fastq.gz"/>
+            <output name="out2" decompress="true" file="cutadapt_out2_internal_adapter.fq.gz" ftype="fastq.gz"/>
             <assert_command>
-                <has_text text="AGATCGGAAGAGCX"/>
+                <has_text text="'AGATCGGAAGAGCX'" n="2"/>
             </assert_command>
         </test>
         <test expect_num_outputs="1">
@@ -1095,12 +1060,9 @@
                     </conditional>
                 </repeat>
             </section>
-            <section name="adapter_options">
-                <param name="internal" value="X"/>
-            </section>
             <output name="out1" file="cutadapt_builtin_internal_adapter.out" ftype="fastq"/>
             <assert_command>
-                <has_text text="TGTAGGCCX"/>
+                <has_text text="'TGTAGGCC'"/>
             </assert_command>
         </test>
         <!-- Ensure individual per adapter noindels parameter works -->
@@ -1123,16 +1085,16 @@
             </section>
             <section name="r2">
                 <repeat name="adapters2">
-                    <conditional name="adapter_source2">
-                        <param name="adapter_source_list2" value="user"/>
-                        <param name="adapter2" value="AGATCGGAAGAGC"/>
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="AGATCGGAAGAGC"/>
                     </conditional>
                     <param name="single_noindels" value=";noindels" />
                 </repeat>
             </section>
             <output_collection name="out_pairs" type="paired">
-                <element name="forward" decompress="True" file="cutadapt_out1.fq.gz" ftype="fastq.gz" />
-                <element name="reverse" decompress="True" file="cutadapt_out2.fq.gz" ftype="fastq.gz" />
+                <element name="forward" decompress="true" file="cutadapt_out1.fq.gz" ftype="fastq.gz" />
+                <element name="reverse" decompress="true" file="cutadapt_out2.fq.gz" ftype="fastq.gz" />
             </output_collection>
         </test>
         <!-- Ensure specifying quality cutoff (for both reads) works -->
@@ -1155,17 +1117,200 @@
             </section>
             <section name="r2">
                 <repeat name="adapters2">
-                    <conditional name="adapter_source2">
-                        <param name="adapter_source_list2" value="user"/>
-                        <param name="adapter2" value="AGATCGGAAGAGC"/>
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="AGATCGGAAGAGC"/>
                     </conditional>
                 </repeat>
                 <param name="quality_cutoff2" value="15,20"/>
             </section>
             <output_collection name="out_pairs" type="paired">
-                <element name="forward" decompress="True" file="cutadapt_out1.fq.gz" ftype="fastq.gz" />
-                <element name="reverse" decompress="True" file="cutadapt_out2_cutoff.fq.gz" ftype="fastq.gz" />
+                <element name="forward" decompress="true" file="cutadapt_out1.fq.gz" ftype="fastq.gz" />
+                <element name="reverse" decompress="true" file="cutadapt_out2_cutoff.fq.gz" ftype="fastq.gz" />
+            </output_collection>
+            <assert_command>
+                <has_text text="--quality-cutoff=5"/>
+                <has_text text="-Q=15,20"/>
+            </assert_command>
+        </test>
+
+        <!-- ployA trimmining https://github.com/marcelm/cutadapt/blob/e04cc32e392e1cbe0c518b4e0637cdf03533d440/tests/test_paired.py#L768 -->
+        <test expect_num_outputs="3">
+            <param name="type" value="paired_collection" />
+            <param name="input_1">
+                <collection type="paired">
+                    <element name="forward" ftype="fasta" value="cutadapt/data/polya.1.fasta" />
+                    <element name="reverse" ftype="fasta" value="cutadapt/data/polya.2.fasta" />
+                </collection>
+            </param>
+            <param name="poly_a" value="true"/>
+            <output_collection name="out_pairs" type="paired">
+                <element name="forward" file="cutadapt/cut/polya.1.fasta" ftype="fasta" />
+                <element name="reverse" file="cutadapt/cut/polya.2.fasta" ftype="fasta" />
             </output_collection>
+            <assert_command>
+                <has_text text="--poly-a"/>
+            </assert_command>
+        </test>
+
+        <!-- polyA legacy https://github.com/marcelm/cutadapt/blob/e04cc32e392e1cbe0c518b4e0637cdf03533d440/tests/test_commandline.py#L267 -->
+        <test expect_num_outputs="1">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fasta" value="cutadapt/data/polya.1.fasta" />
+            <section name="r1">
+                <repeat name="adapters">
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"/>
+                    </conditional>
+                </repeat>
+            </section>
+            <param name="overlap" value="10"/>
+            <output name="out1" file="cutadapt/cut/polya.legacy.1.fasta" ftype="fasta"/>
+            <assert_command>
+                <has_text text="-a 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'"/>
+                <has_text text="--overlap=10"/>
+            </assert_command>
+        </test>
+
+        <!-- polyA legacy brace notation https://github.com/marcelm/cutadapt/blob/e04cc32e392e1cbe0c518b4e0637cdf03533d440/tests/test_commandline.py#L276 -->
+        <test expect_num_outputs="1">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fasta" value="cutadapt/data/polya.1.fasta" />
+            <section name="r1">
+                <repeat name="adapters">
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="A{35}"/>
+                    </conditional>
+                </repeat>
+            </section>
+            <param name="overlap" value="10"/>
+            <output name="out1" file="cutadapt/cut/polya.legacy.1.fasta" ftype="fasta"/>
+            <assert_command>
+                <has_text text="-a 'A{35}'"/>
+                <has_text text="--overlap=10"/>
+            </assert_command>
+        </test>
+
+        <!-- polyA https://github.com/marcelm/cutadapt/blob/e04cc32e392e1cbe0c518b4e0637cdf03533d440/tests/test_commandline.py#L281 -->
+        <test expect_num_outputs="1">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fasta" value="cutadapt/data/polya.1.fasta" />
+            <param name="poly_a" value="true"/>
+            <output name="out1" file="cutadapt/cut/polya.1.fasta" ftype="fasta"/>
+            <assert_command>
+                <has_text text="--poly-a"/>
+            </assert_command>
+        </test>
+
+        <!-- fasta.gz input https://github.com/marcelm/cutadapt/blob/e04cc32e392e1cbe0c518b4e0637cdf03533d440/tests/test_commandline.py#L78 
+             in contrast to the original test the tool automatically compresses the output -->
+        <test expect_num_outputs="1">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fasta.gz" value="cutadapt/data/simple.fasta.gz" />
+            <output name="out1" decompress="true" file="cutadapt/cut/simple.fasta.gz" ftype="fasta.gz"/>
+        </test>
+
+        <!-- fatstqillumina input https://github.com/marcelm/cutadapt/blob/e04cc32e392e1cbe0c518b4e0637cdf03533d440/tests/test_commandline.py#L252 -->
+        <test expect_num_outputs="1">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fastqillumina" value="cutadapt/data/illumina64.fastq" />
+            <section name="r1">
+                <repeat name="adapters">
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="XXXXXX"/>
+                    </conditional>
+                </repeat>
+            </section>
+            <param name="quality_cutoff" value="10"/>
+            <output name="out1" file="cutadapt/cut/illumina64.fastq" ftype="fastqillumina"/>
+            <assert_command>
+                <has_text text="-a 'XXXXXX'"/>
+                <has_text text="--quality-cutoff=10"/>
+                <has_text text="--quality-base=64"/>
+            </assert_command>
+        </test>
+        <!-- fatstqillumina input https://github.com/marcelm/cutadapt/blob/e04cc32e392e1cbe0c518b4e0637cdf03533d440/tests/test_commandline.py#L257 -->
+        <test expect_num_outputs="1">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fastqillumina" value="cutadapt/data/illumina64.fastq" />
+            <param name="quality_cutoff" value="10"/>
+            <output name="out1" file="cutadapt/cut/illumina64.fastq" ftype="fastqillumina"/>
+            <assert_command>
+                <has_text text="--quality-cutoff=10"/>
+                <has_text text="--quality-base=64"/>
+            </assert_command>
+        </test>
+
+        <!-- https://github.com/marcelm/cutadapt/blame/3407ac0004d04b11ae7157934a6665ecaf82c328/tests/test_commandline.py#L1028 --> 
+        <test expect_num_outputs="3">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fastqillumina" value="cutadapt/data/maxee.fastq" />
+            <param name="max_expected_errors" value="0.9"/>
+            <param name="output_selector" value="report,info_file"/>
+            <output name="out1" file="cutadapt/cut/maxee.fastq" ftype="fastqillumina"/>
+            <output name="report">
+                <assert_contents>
+                    <has_text text="Reads with too many exp. errors:             2"/>
+                </assert_contents>
+            </output>
+            <output name="info_file">
+                <assert_contents>
+                    <has_n_lines n="4"/>
+                    <has_text text="ee_0.8&#09;-1&#09;ACGTTGCA&#09;++++++++"/>
+                </assert_contents>
+            </output>
+            <assert_command>
+                <has_text text="--max-expected-errors=0.9"/>
+            </assert_command>
+        </test>
+
+        <!-- https://github.com/marcelm/cutadapt/blob/3407ac0004d04b11ae7157934a6665ecaf82c328/tests/test_commandline.py#L335 -->
+        <test expect_num_outputs="1">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fasta" value="cutadapt/data/wildcard.fa" />
+            <section name="r1">
+                <repeat name="anywhere_adapters">
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="ACGTACGT"/>
+                    </conditional>
+                </repeat>
+            </section>
+            <section name="adapter_options">
+                <param name="match_read_wildcards" value="true"/>
+            </section>
+            <output name="out1" file="cutadapt/cut/wildcard.fa" ftype="fasta" sort="true"/>
+            <assert_command>
+                <has_text text="--match-read-wildcards"/>
+                <has_text text="-b 'ACGTACGT'"/>
+            </assert_command>
+        </test>
+
+        <!-- https://github.com/marcelm/cutadapt/blob/3407ac0004d04b11ae7157934a6665ecaf82c328/tests/test_commandline.py#L368 -->
+        <test expect_num_outputs="1">
+            <param name="type" value="single" />
+            <param name="input_1" ftype="fasta" value="cutadapt/data/wildcardN.fa" />
+            <section name="r1">
+                <repeat name="adapters">
+                    <conditional name="adapter_source">
+                        <param name="adapter_source_list" value="user"/>
+                        <param name="adapter" value="GGGGGGG"/>
+                    </conditional>
+                </repeat>
+            </section>
+            <section name="adapter_options">
+                <param name="match_read_wildcards" value="true"/>
+                <param name="error_rate" value="0"/>
+            </section>
+            <output name="out1" file="cutadapt/cut/wildcardN.fa" ftype="fasta" sort="true"/>
+            <assert_command>
+                <has_text text="--match-read-wildcards"/>
+                <has_text text="--error-rate=0.0"/>
+                <has_text text="-a 'GGGGGGG'"/>
+            </assert_command>
         </test>
     </tests>
 
--- a/macros.xml	Fri May 19 21:42:14 2023 +0000
+++ b/macros.xml	Sun Dec 17 18:52:25 2023 +0000
@@ -1,7 +1,7 @@
 <macros>
-    <token name="@TOOL_VERSION@">4.4</token>
+    <token name="@TOOL_VERSION@">4.6</token>
     <token name="@VERSION_SUFFIX@">0</token>
-    <token name="@FASTQ_TYPES@">fastq.gz,fastq,fasta</token>
+    <token name="@FASTQ_TYPES@">fastq.bz2,fastq.gz,fastq,fasta.bz2,fasta.gz,fasta</token>
     <xml name="edam_ontology">
         <edam_topics>                                                                                  
             <edam_topic>topic_0632</edam_topic>
@@ -25,46 +25,41 @@
             <xref type='bio.tools'>cutadapt</xref>
         </xrefs>
     </xml>
+
+    <!-- parametrized token - you need to set `$ADAPTER_ARGUMENT` -->
+    <token name="@adapter_cli@">
+        #if $a.adapter_source.adapter_source_list == 'builtin':
+            $ADAPTER_ARGUMENT '${a.adapter_source.adapter.fields.name}'='${a.adapter_source.adapter}${a.single_noindels}'
+        #else if $a.adapter_source.adapter_source_list == 'file':
+            $ADAPTER_ARGUMENT file:'${a.adapter_source.adapter_file}${a.single_noindels}'
+        #else if str($a.adapter_source.adapter_name) != "":
+            $ADAPTER_ARGUMENT '${a.adapter_source.adapter_name}'='${a.adapter_source.adapter}${a.single_noindels}'
+        #else
+            $ADAPTER_ARGUMENT '${a.adapter_source.adapter}${a.single_noindels}'
+         #end if
+    </token>
+
      <token name="@read1_options@"><![CDATA[
 
         ## Read1 trimming
 
+        #set ADAPTER_ARGUMENT="-a"
         #for $a in $library.r1.adapters
-            #if $a.adapter_source.adapter_source_list == 'builtin':
-                -a '${a.adapter_source.adapter.fields.name}'='${a.adapter_source.adapter}${adapter_options.internal}${a.single_noindels}'
-            #else if $a.adapter_source.adapter_source_list == 'file':
-                -a file:'${a.adapter_source.adapter_file}${adapter_options.internal}${a.single_noindels}'
-            #else if str($a.adapter_source.adapter_name) != "":
-                -a '${a.adapter_source.adapter_name}'='${a.adapter_source.adapter}${adapter_options.internal}${a.single_noindels}'
-            #else
-                -a '${a.adapter_source.adapter}${adapter_options.internal}${a.single_noindels}'
-            #end if
+            @adapter_cli@
         #end for
-        #for $aa in $library.r1.anywhere_adapters
-            #if $aa.anywhere_adapter_source.anywhere_adapter_source_list == 'builtin':
-                -b '${aa.anywhere_adapter_source.anywhere_adapter.fields.name}'='${aa.anywhere_adapter_source.anywhere_adapter}${aa.single_noindels}'
-            #else if $aa.anywhere_adapter_source.anywhere_adapter_source_list == 'file':
-                -b file:'${aa.anywhere_adapter_source.anywhere_adapter_file}${aa.single_noindels}'
-            #else if str($aa.anywhere_adapter_source.anywhere_adapter_name) != "":
-                -b '${aa.anywhere_adapter_source.anywhere_adapter_name}'='${aa.anywhere_adapter_source.anywhere_adapter}${aa.single_noindels}'
-            #else
-                -b '${aa.anywhere_adapter_source.anywhere_adapter}${aa.single_noindels}'
-            #end if
+        
+        #set ADAPTER_ARGUMENT="-b"
+        #for $a in $library.r1.anywhere_adapters
+            @adapter_cli@
         #end for
-        #for $fa in $library.r1.front_adapters
-            #if $fa.front_adapter_source.front_adapter_source_list == 'builtin':
-                -g '${fa.front_adapter_source.front_adapter.fields.name}'='${adapter_options.internal}${fa.front_adapter_source.front_adapter}${fa.single_noindels}'
-            #else if $fa.front_adapter_source.front_adapter_source_list == 'file':
-                -g file:'${adapter_options.internal}${fa.front_adapter_source.front_adapter_file}${fa.single_noindels}'
-            #else if str($fa.front_adapter_source.front_adapter_name) != "":
-                -g '${fa.front_adapter_source.front_adapter_name}'='${adapter_options.internal}${fa.front_adapter_source.front_adapter}${fa.single_noindels}'
-            #else
-                -g '${adapter_options.internal}${fa.front_adapter_source.front_adapter}${fa.single_noindels}'
-            #end if
+        
+        #set ADAPTER_ARGUMENT="-g"
+        #for $a in $library.r1.front_adapters
+            @adapter_cli@
         #end for
 
-        #if str($library.r1.cut) != '0':
-            -u $library.r1.cut
+        #if str($cut) != '0':
+            -u $cut
         #end if
 
         ## Additional Outputs
@@ -94,38 +89,17 @@
 
         ## Read2 trimming
 
+        #set ADAPTER_ARGUMENT="-A"
         #for $a in $library.r2.adapters2
-            #if $a.adapter_source2.adapter_source_list2 == 'builtin':
-                -A '${a.adapter_source2.adapter2.fields.name}'='${a.adapter_source2.adapter2}${adapter_options.internal}${a.single_noindels}'
-            #else if $a.adapter_source2.adapter_source_list2 == 'file':
-                -A file:'${a.adapter_source2.adapter_file2}${adapter_options.internal}${a.single_noindels}'
-            #else if str($a.adapter_source2.adapter_name2) != "":
-                -A '${a.adapter_source2.adapter_name2}'='${a.adapter_source2.adapter2}${adapter_options.internal}${a.single_noindels}'
-            #else
-                -A '${a.adapter_source2.adapter2}${adapter_options.internal}${a.single_noindels}'
-            #end if
+            @adapter_cli@
         #end for
-        #for $aa in $library.r2.anywhere_adapters2
-            #if $aa.anywhere_adapter_source2.anywhere_adapter_source_list2 == 'builtin':
-                -B '${aa.anywhere_adapter_source2.anywhere_adapter2.fields.name}'='${aa.anywhere_adapter_source2.anywhere_adapter2}${aa.single_noindels}'
-            #else if $aa.anywhere_adapter_source2.anywhere_adapter_source_list2 == 'file':
-                -B file:'${aa.anywhere_adapter_source2.anywhere_adapter_file2}${aa.single_noindels}'
-            #else if str($aa.anywhere_adapter_source2.anywhere_adapter_name2) != "":
-                -B '${aa.anywhere_adapter_source2.anywhere_adapter_name2}'='${aa.anywhere_adapter_source2.anywhere_adapter2}${aa.single_noindels}'
-            #else
-                -B '${aa.anywhere_adapter_source2.anywhere_adapter2}'
-            #end if
+        #set ADAPTER_ARGUMENT="-B"
+        #for $a in $library.r2.anywhere_adapters2
+            @adapter_cli@
         #end for
-        #for $fa in $library.r2.front_adapters2
-            #if $fa.front_adapter_source2.front_adapter_source_list2 == 'builtin':
-                -G '${fa.front_adapter_source2.front_adapter2.fields.name}'='${adapter_options.internal}${fa.front_adapter_source2.front_adapter2}${fa.single_noindels}'
-            #else if $fa.front_adapter_source2.front_adapter_source_list2  == 'file':
-                -G file:'${adapter_options.internal}${fa.front_adapter_source2.front_adapter_file2}${fa.single_noindels}'
-            #else if str($fa.front_adapter_source2.front_adapter_name2) != "":
-                -G '${fa.front_adapter_source2.front_adapter_name2}'='${adapter_options.internal}${fa.front_adapter_source2.front_adapter2}${fa.single_noindels}'
-            #else
-                -G '${adapter_options.internal}${fa.front_adapter_source2.front_adapter2}${fa.single_noindels}'
-            #end if
+        #set ADAPTER_ARGUMENT="-G"
+        #for $a in $library.r2.front_adapters2
+            @adapter_cli@
         #end for
 
         #if str($library.r2.cut2) != '0':
@@ -182,97 +156,46 @@
             </sanitizer>
         </xml>
         
-        <xml name="adapter" token_name="" token_argument="" token_value="" token_label="">
-            <param name="@NAME@" argument="@ARGUMENT@" type="text" value="@VALUE@" label="@LABEL@">
-                <expand macro="adapter_sanitizer"/>
-            </param>
-        </xml>
-        
-        <xml name="adapter_select" token_name="" token_argument="" token_label="">
-            <param name="@NAME@" argument="@ARGUMENT@" type="select" label="@LABEL@">
-                <options from_data_table="adapters">
-                    <filter type="sort_by" column="1" />
-                </options>
-                <expand macro="adapter_sanitizer"/>
-            </param>
+        <xml name="adapter_conditional" tokens="adapter_type,argument">
+            <conditional name="adapter_source">
+                <param name="adapter_source_list" type="select" label="Source" >
+                    <option value="builtin" selected="true">Standard (select from the list below)</option>
+                    <option value="user">Enter custom sequence</option>
+                    <option value="file">File from history</option>
+                </param>
+                <when value="user">
+                    <param name="adapter_name" type="text" value="" optional="true" label="Custom @ADAPTER_TYPE@ adapter name" help="Optional if 'Multiple output' is selected in the Outputs selector'" />
+                    <param name="adapter" argument="@ARGUMENT@" type="text" value="AATTGGCC" label="Custom @ADAPTER_TYPE@ adapter sequence">
+                        <expand macro="adapter_sanitizer"/>
+                    </param>
+                </when>
+                <when value="builtin">
+                    <param name="adapter" argument="@ARGUMENT@" type="select" label="@ADAPTER_TYPE@ adapter">
+                        <options from_data_table="adapters">
+                            <filter type="sort_by" column="1" />
+                            </options>
+                        <expand macro="adapter_sanitizer"/>
+                    </param>
+                </when>
+                <when value="file">
+                    <param name="adapter_file" argument="@ARGUMENT@" format="fasta" type="data"  label="File containing @ADAPTER_TYPE@ adapters" help="Should be of datatype FASTA" />
+                </when>
+            </conditional>
+            <param name="single_noindels" type="boolean" truevalue=";noindels" falsevalue="" checked="false" label="Disallow indels for this adapter"/>
         </xml>
 
         <xml name="single_end_options" >
-
-            <section name="r1" title="Read 1 Options" expanded="True">
-
+            <section name="r1" title="Read 1 Options" expanded="true">
                 <repeat name="adapters" title="3' (End) Adapters" help="Sequence of an adapter ligated to the 3' end (paired data: of the first read). The adapter and subsequent bases are trimmed. If a '$' character is appended ('anchoring'), the adapter is only found if it is a suffix of the read. To search for a linked adapter, separate the 2 sequences with 3 dots (ADAPTER1...ADAPTER2), see Help below.">
-                    <conditional name="adapter_source">
-                        <param name="adapter_source_list" type="select" label="Source" >
-                            <option value="builtin" selected="True">Standard (select from the list below)</option>
-                            <option value="user">Enter custom sequence</option>
-                            <option value="file">File from history</option>
-                        </param>
-
-                        <when value="user">
-                            <param name="adapter_name" type="text" value="" optional="True" label="Enter custom 3' adapter name (Optional if Multiple output is 'No')" />
-                            <expand macro="adapter" name="adapter" argument="-a" type="text" value="AATTGGCC" label="Enter custom 3' adapter sequence" />
-                        </when>
-
-                        <when value="builtin">
-                            <expand macro="adapter_select" name="adapter" argument="-a" label="Choose 3' adapter"/>
-                        </when>
-
-                        <when value="file">
-                            <param name="adapter_file" argument="-a" format="fasta" type="data" help="Should be of datatype FASTA" label="Choose file containing 3' adapters" />
-                        </when>
-                    </conditional>
-                    <param name="single_noindels" type="boolean" truevalue=";noindels" falsevalue="" checked="false" label="Disallow indels for this adapter"/>
+                    <expand macro="adapter_conditional" argument="-a" adapter_type="3'"/>
                 </repeat>
-
                 <repeat name="front_adapters" title="5' (Front) Adapters" help="Sequence of an adapter ligated to the 5' end (paired data: of the first read). The adapter and any preceding bases are trimmed. Partial matches at the 5' end are allowed. If a '^' character is prepended ('anchoring'), the adapter is only found if it is a prefix of the read. To search for a linked adapter, separate the 2 sequences with 3 dots (ADAPTER1...ADAPTER2), see Help below.">
-                    <conditional name="front_adapter_source">
-                        <param name="front_adapter_source_list" type="select" label="Source">
-                            <option value="builtin" selected="True">Standard (select from the list below)</option>
-                            <option value="user">Enter custom sequence</option>
-                            <option value="file">File from history</option>
-                        </param>
-
-                        <when value="user">
-                            <param name="front_adapter_name" type="text" value="" optional="True" label="Enter custom 5' adapter name (Optional if Multiple output is 'No')" />
-                            <expand macro="adapter" name="front_adapter" argument="-g" value="AATTGGCC" label="Enter custom 5' adapter sequence" />
-                        </when>
-                        <when value="builtin">
-                            <expand macro="adapter_select" name="front_adapter" argument="-g" label="Choose 5' adapter"/>
-                        </when>
-                        <when value="file">
-                            <param name="front_adapter_file" argument="-g" format="fasta" type="data" help="Should be of datatype &quot;FASTA&quot;" label="Choose file containing 5' adapters" />
-                        </when>
-                    </conditional>
-                    <param name="single_noindels" type="boolean" truevalue=";noindels" falsevalue="" checked="false" label="Disallow indels for this adapter"/>
+                    <expand macro="adapter_conditional" argument="-g" adapter_type="5'"/>
                 </repeat>
-
                 <repeat name="anywhere_adapters" title="5' or 3' (Anywhere) Adapters" help="Sequence of an adapter that may be ligated to the 5' or 3' end (paired data: of the first read). Both types of matches as described under 3' und 5' Adapters are allowed. If the first base of the read is part of the match, the behavior is as with 5' Adapters, otherwise as with 3' Adapters. This option is mostly for rescuing failed library preparations - do not use if you know which end your adapter was ligated to!">
-                    <conditional name="anywhere_adapter_source">
-                        <param name="anywhere_adapter_source_list" type="select" label="Source">
-                            <option value="builtin" selected="True">Standard (select from the list below)</option>
-                            <option value="user">Enter custom sequence</option>
-                            <option value="file">File from history</option>
-                        </param>
-
-                        <when value="user">
-                            <param name="anywhere_adapter_name" type="text" value="" optional="True" label="Enter custom 5' or 3' adapter name (Optional if Multiple output is 'No')"  />
-                            <expand macro="adapter" name="anywhere_adapter" argument="-b" value="AATTGGCC" label="Enter custom 5' or 3' adapter sequence" />
-                        </when>
-                        <when value="builtin">
-                            <expand macro="adapter_select" name="anywhere_adapter" argument="-b" label="Choose 5' or 3' adapter"/>
-                        </when>
-                        <when value="file">
-                            <param name="anywhere_adapter_file" argument="-b" format="fasta" type="data" help="Should be of datatype &quot;FASTA&quot;" label="Choose file containing 3' or 5' adapters" />
-                        </when>
-                    </conditional>
-                    <param name="single_noindels" type="boolean" truevalue=";noindels" falsevalue="" checked="false" label="Disallow indels for this adapter"/>
+                    <expand macro="adapter_conditional" argument="-b" adapter_type="5' or 3'"/>
                 </repeat>
-
-                <param argument="--cut" type="integer" value="0" optional="True" label="Cut bases from reads before adapter trimming" help="Remove bases from each read (first read only if paired). If positive, remove bases from the beginning. If negative, remove bases from the end. This is applied *before* adapter trimming." />
-
             </section>
-
         </xml>
 
         <xml name="paired_end_options" >
@@ -281,84 +204,29 @@
             <expand macro="single_end_options" />
 
             <!-- Read 2 Options -->
-            <section name="r2" title="Read 2 Options" expanded="True">
-
+            <section name="r2" title="Read 2 Options" expanded="true">
                 <repeat name="adapters2" title="3' (End) Adapters" help="Sequence of an adapter ligated to the 3' end of the second read in each pair. The adapter and subsequent bases are trimmed. If a '$' character is appended ('anchoring'), the adapter is only found if it is a suffix of the read. To search for a linked adapter, separate the 2 sequences with 3 dots (ADAPTER1...ADAPTER2), see Help below.">
-                    <conditional name="adapter_source2">
-                        <param name="adapter_source_list2" type="select" label="Source" >
-                            <option value="builtin" selected="True">Standard (select from the list below)</option>
-                            <option value="user">Enter custom sequence</option>
-                            <option value="file">File from history</option>
-                        </param>
-
-                        <when value="user">
-                            <param name="adapter_name2" type="text" value="" optional="True" label="Enter custom 3' adapter name (Optional)" />
-                            <expand macro="adapter" name="adapter2" argument="-A" label="Enter custom 3' adapter sequence" value="AATTGGCC" />
-                        </when>
-
-                        <when value="builtin">
-                            <expand macro="adapter_select" name="adapter2" argument="-A" label="Choose 3' adapter"/>
-                        </when>
-                        <when value="file">
-                            <param name="adapter_file2" argument="-a" format="fasta" type="data" help="Should be of datatype &quot;FASTA&quot;" label="Choose file containing 3' adapters" />
-                        </when>
-                    </conditional>
-                    <param name="single_noindels" type="boolean" truevalue=";noindels" falsevalue="" checked="false" label="Disallow indels for this adapter"/>
+                    <expand macro="adapter_conditional" argument="-A" adapter_type="3'"/>
+                </repeat>
+                <repeat name="front_adapters2" title="5' (Front) Adapters" help="Sequence of an adapter ligated to the 5' end of the second read in each pair. The adapter and any preceding bases are trimmed. Partial matches at the 5' end are allowed. If a '^' character is prepended ('anchoring'), the adapter is only found if it is a prefix of the read. To search for a linked adapter, separate the 2 sequences with 3 dots (ADAPTER1...ADAPTER2), see Help below.">
+                    <expand macro="adapter_conditional" argument="-G" adapter_type="5'"/>
+                </repeat>
+                <repeat name="anywhere_adapters2" title="5' or 3' (Anywhere) Adapters" help="Sequence of an adapter that may be ligated to the 5' or 3' end of the second read in each pair. Both types of matches as described under under 3' und 5' Adapters are allowed. If the first base of the read is part of the match, the behavior is as with 5' Adapters, otherwise as with 3' Adapters. This option is mostly for rescuing failed library preparations - do not use if you know which end your adapter was ligated to!">
+                    <expand macro="adapter_conditional" argument="-B" adapter_type="5' or 3'"/>
                 </repeat>
 
-                <repeat name="front_adapters2" title="5' (Front) Adapters" help="Sequence of an adapter ligated to the 5' end of the second read in each pair. The adapter and any preceding bases are trimmed. Partial matches at the 5' end are allowed. If a '^' character is prepended ('anchoring'), the adapter is only found if it is a prefix of the read. To search for a linked adapter, separate the 2 sequences with 3 dots (ADAPTER1...ADAPTER2), see Help below.">
-                    <conditional name="front_adapter_source2">
-                        <param name="front_adapter_source_list2" type="select" label="Source">
-                            <option value="builtin" selected="True">Standard (select from the list below)</option>
-                            <option value="user">Enter custom sequence</option>
-                            <option value="file">File from history</option>
-                        </param>
-
-                        <when value="user">
-                            <param name="front_adapter_name2" type="text" value="" label="Enter custom 5' adapter name (Optional)" />
-                            <expand macro="adapter" name="front_adapter2" argument="-G" value="AATTGGCC" label="Enter custom 5' adapter sequence" />
-                        </when>
-                        <when value="builtin">
-                            <expand macro="adapter_select" name="front_adapter2" argument="-G" label="Choose 5' adapter"/>
-                        </when>
-                        <when value="file">
-                            <param name="front_adapter_file2" argument="-g" format="fasta" type="data" help="Should be of datatype &quot;FASTA&quot;" label="Choose file containing 5' adapters" />
-                        </when>
-                    </conditional>
-                    <param name="single_noindels" type="boolean" truevalue=";noindels" falsevalue="" checked="false" label="Disallow indels for this adapter"/>
-                </repeat>
-
-                <repeat name="anywhere_adapters2" title="5' or 3' (Anywhere) Adapters" help="Sequence of an adapter that may be ligated to the 5' or 3' end of the second read in each pair. Both types of matches as described under under 3' und 5' Adapters are allowed. If the first base of the read is part of the match, the behavior is as with 5' Adapters, otherwise as with 3' Adapters. This option is mostly for rescuing failed library preparations - do not use if you know which end your adapter was ligated to!">
-                    <conditional name="anywhere_adapter_source2">
-                        <param name="anywhere_adapter_source_list2" type="select" label="Source">
-                            <option value="builtin" selected="True">Standard (select from the list below)</option>
-                            <option value="user">Enter custom sequence</option>
-                            <option value="file">File from history</option>
-                        </param>
-
-                        <when value="user">
-                            <param name="anywhere_adapter_name2" type="text" value="" optional="True" label="Enter custom 5' or 3' adapter name (Optional)" />
-                            <expand macro="adapter" name="anywhere_adapter2" argument="-B" label="Enter custom 5' or 3' adapter sequence" value="AATTGGCC" />
-                        </when>
-                        <when value="builtin">
-                            <expand macro="adapter_select" name="anywhere_adapter2" argument="-B" type="select" label="Choose 5' or 3' adapter"/>
-                        </when>
-                        <when value="file">
-                            <param name="anywhere_adapter_file2" argument="-b" format="fasta" type="data" help="Should be of datatype &quot;FASTA&quot;" label="Choose file containing 3' or 5' adapters" />
-                        </when>
-                    </conditional>
-                    <param name="single_noindels" type="boolean" truevalue=";noindels" falsevalue="" checked="false" label="Disallow indels for this adapter"/>
-                </repeat>
-
-            <param name="cut2" argument="-U" type="integer" value="0" optional="True" label="Cut bases from the second read in each pair." help="Remove bases from the beginning or end of each read before trimming adapters. If positive, the bases are removed from the beginning of each read. If negative, the bases are removed from the end of each read." />
-            <param name="quality_cutoff2" type="text" optional="true" label="Optional separate quality cutoff for Read 2" help="Trim low-quality bases from 5' and/or 3' ends of each read before adapter removal. If one value is given, only the 3' end is trimmed. If two comma-separated cutoffs are given, the 5' end is trimmed with the first cutoff, the 3' end with the second. Leave blank to use the same value as for Read 1">
-                <sanitizer>
-                    <valid initial="string.digits"><add value="," /></valid>
-                </sanitizer>
-                <validator type="regex">[0-9,]+</validator>
-            </param>
+                <!-- read modification -->
+                <param name="cut2" argument="-U" type="integer" value="0" optional="true" label="Cut bases from the second read in each pair." help="Remove bases from the beginning or end of each read before trimming adapters. If positive, the bases are removed from the beginning of each read. If negative, the bases are removed from the end of each read." />
+                <param name="quality_cutoff2" argument="-Q" type="text" optional="true" label="Optional separate quality cutoff for Read 2" help="Trim low-quality bases from 5' and/or 3' ends of each read before adapter removal. If one value is given, only the 3' end is trimmed. If two comma-separated cutoffs are given, the 5' end is trimmed with the first cutoff, the 3' end with the second. Leave blank to use the same value as for Read 1">
+                    <sanitizer>
+                        <valid initial="string.digits"><add value="," /></valid>
+                    </sanitizer>
+                    <validator type="regex">[0-9]+(,[0-9])?</validator>
+                </param>
+                <!-- read filtering-->
+                <param name="minimum_length2" type="integer" min="0" value="" optional="true" label="Minimum length (R2)" />
+                <param name="maximum_length2" type="integer" min="0" value="" optional="true" label="Maximum length (R2)" />
             </section>
-
         </xml>
 
         <xml name="inherit_format_1">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/cut/illumina64.fastq	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,80 @@
+@14569
+AAGTTTATTCCTGGACGAAGGAAGAAAAGGCCAGATGGGAAACAAGAACAAGCCCCTGTTGAAGACGCAGGGCC
++
+cceeeeceeeee`dedbdbdb_^b`abU_cacadabd`dLMZ[XTcT^a^adaaaddcd`aL^`^_`Y\]^`Y_
+@19211
+AGA
++
+^\`
+@9180
+GAGGG
++
+b`bLb
+@19132
+TGTGATTATCCACTGGTATAT
++
+Z[QZZLZ[]J[SHZNaZ[_Ia
+@15868
+CTGCCAAGGCTGCCCCCAAA
++
+`c`cc\`\Lb]bL`[`a]L`
+@1424
+GGCCCCAGACTTGCTCCCCCAACAAGGACAATGTCCAAGGAGTGTCCCC
++
+eeeeeeeea`bbdaaadad`Oaaaaccada_aa_d`_X`_^`[`_[_W^
+@7855
+GTGGGGGCT
++
+]^\]FW]Z`
+@17943
+ACATGGGACCAGAAAACACCACCAGGGGTTTGGGGCTGTCCTGAG
++
+ccc`\^`aba\b^`\FR`OOPYG[[W```[Ra_RR_\]\\P\_H_
+@11100
+CGGATAACTGAAAATGCATTTTTAACGCCATGACCGTGTCTCAAGGACCCGCTGTGGAAG
++
+b`b_b_a\bc^Tabadaddcddd``bdaa_^aJ\^_\]\\__O[___L^\_aaa^^^UJ^
+@15663
+AGGT
++
+aaKa
+@4698
+CCAATTGGCACCCCTCTGCCTTCAGCCATT
++
+cccc\`ccc\caccZccccc]^`LY\bL_b
+@20649
+TCTGGACTGGATCTTTAGGATGGTGGAGATGATCTGGATGTAGGACAAAAGAACCAGGCAGAAGGGTG
++
+eeeeeaddadacdddebeccdddadd\^abbT_]bccTac]]b]L^][]Ve[^ZaY_^_^`\\Y]^Y`
+@17259
+
++
+
+@6003
+CTTCAACTCATCTTGTTATTAATACCATCAATATCCCATGAGGCTCATAAAACGAGTCTTTCTTCTTGGAAACATGACCAAGATTGGGCAAACGT
++
+fffffffffffffffffdffecfcefeffdcfdeeebbbdbccccc\db\`^aa`^Y^^^cbcbaa`bbWY^^^__S_YYR]GWY]\]]XX\_`S
+@4118
+TCAAATTGTACTGCAAAGAAGGTCCCAGCTGGTCTCTTCTGGGAGTGATCTAACTAACTTAAG
++
+dc^ddeeeeeedeee`ceceddadadddcbde_dedc_ec_a^^b\b\\]VIPZY^T^^^\L_
+@18416
+GTGGGGAAGCCGAAGAAGCAGCGGAGATCGATTGTAAGAACGACG
++
+dddacaabdbea\d^cce\da`dd_^__`a`a`b[_^__^\^^^_
+@20115
+TGAAAAAGGAAAACATGGTAGTTTTCTTGTATGAGAGAGCCAGAGCCACCTTGGAGATTTTGTTCTCTCTGTGCG
++
+ed^eeafffaddfecdddabc^_badd`bd_ddadaa^bbcad\d\__^_\aaa_aY____aaN_\cdc\^aaYb
+@16139
+TCATCCGAAGAGTTGGCAGGCCCTGTGAATTGTGAAAACAGTATACCCACCCCTTTCCC
++
+cabacacY^c\daaddaadad^\ad_a\Y`[ZQ]Y^^OYQ^X^YT\\]U\^RRX^\YJ^
+@14123
+GATTTGGGGAAAGGAAACAATAGTTGAGTTTGGGCCACGGGAAATTCAAGATGCCTGGTATGTC
++
+cccccccac^bYbbT_aa_Yb^^Ta\\^]]aaTaaaaab\b\XL`VZZV]QYYY[aa^^^^_^^
+@8766
+ACCTGTAAGGTCCGCTCCTGGTGGACACCCACGAAGTCCAGGGCCTCAGGCAGGAAGTTGTAGCGCAGAGTTTTGAGCAGCTGCTCCATC
++
+fcfffffcffeffeeefdefddeecdccacddfdYd`d^\_^`\_abbc\b[ba^Y^Z_^^H^Z_^Y_Y_OKWPZR]]Z]`Z``Z^UHZ^
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/cut/maxee.fastq	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,8 @@
+@empty
+
++
+
+@ee_0.8
+ACGTTGCA
++
+++++++++
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/cut/polya.1.fasta	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,8 @@
+>polyA
+AAACTTCAGAACAG
+>polyAlong
+CTTAGTTCAATWTTAACCAAACTTCAGAACAG
+>polyA2
+AAACTTAACAAGAACAAG
+>nopoly
+GAAGAGTATCTCTCTGTCCTCTTGTCCGGCGTTACAGTAATGATCG
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/cut/polya.2.fasta	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,8 @@
+>polyA
+CTGTTCTGAAGTTT
+>polyAlong
+CTGTTCTGAAGTTTGGTTAAWATTGAACTAAG
+>polyA2
+CTTGTTCTTGTTAAGTTT
+>nopoly
+TCTGAAGTTTGGTTAAWATTGAACTAA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/cut/polya.legacy.1.fasta	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,8 @@
+>polyA
+AAACTTCAG
+>polyAlong
+CTTAGTTCAATWTTAACCAAACTTCAGAACAG
+>polyA2
+AAACTTAAC
+>nopoly
+GAAGAGTATCTCTCTGTCCTCTTGTCCGGCGTTACAGTAATGATCG
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/cut/simple.fasta	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,4 @@
+>first_sequence
+SEQUENCE1
+>second_sequence
+SEQUENCE2
Binary file test-data/cutadapt/cut/simple.fasta.gz has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/cut/wildcard.fa	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,4 @@
+>1
+TGCATGCA
+>2
+TGCATGCA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/cut/wildcardN.fa	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,6 @@
+>perfect
+TTT
+>withN
+TTT
+>1mism
+TTTGGGGCGG
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/data/illumina64.fastq	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,80 @@
+@14569
+AAGTTTATTCCTGGACGAAGGAAGAAAAGGCCAGATGGGAAACAAGAACAAGCCCCTGTTGAAGACGCAGGGCCAACAGGGGCCAACGAAGCTGC
++
+cceeeeceeeee`dedbdbdb_^b`abU_cacadabd`dLMZ[XTcT^a^adaaaddcd`aL^`^_`Y\]^`Y_BBBBBBBBBBBBBBBBBBBBB
+@19211
+AGAGGGCGTGTGATTGCTGGATGTGGGCGGGGGGCCGGGGGAGCCCCATGGGCAGGAGACCTGAGAGCCAGGCGGTGAGGCACTATGAACGCGAG
++
+^\`BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@9180
+GAGGGGCAGCGACTAGTCACCGGACCTGTCAGGCAAGCATAAGCCGTGCGTCAGCACCACGCTGACGGTGCTCCCGCACTCGCGGGACGCGCCAC
++
+b`bLbBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@19132
+TGTGATTATCCACTGGTATATCGGCGTGCCGTCCGCACGAGGAAAAAAGGCATTATTGTTGTGGATCTGTACCATCGTTTGTCCCGTTACCCTTC
++
+Z[QZZLZ[]J[SHZNaZ[_IaBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@15868
+CTGCCAAGGCTGCCCCCAAACCTGGCCCTCCGCGCACCCCACCACGGATCCTGACGTCCTGTCCCCCGCGGCTATGACAGCCAAGTCCCGTCAGC
++
+`c`cc\`\Lb]bL`[`a]L`BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@1424
+GGCCCCAGACTTGCTCCCCCAACAAGGACAATGTCCAAGGAGTGTCCCCTGGGAAGGGTGGGCCTCCCCAGGTGCGGGCGGTGGGCACTGCCCCC
++
+eeeeeeeea`bbdaaadad`Oaaaaccada_aa_d`_X`_^`[`_[_W^BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@7855
+GTGGGGGCTACAATGTGGCTCCAAGTTTTTTCCCGGGAGGTAAGGCCGGGAGCCCCCGCCCTGAGGGGGCGGGAAAGAGGAAGCCCGACGCGGAC
++
+]^\]FW]Z`BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@17943
+ACATGGGACCAGAAAACACCACCAGGGGTTTGGGGCTGTCCTGAGGCTCGGGTAGCAAGCAGCGGGGCTCCGTGTCCAAGCACGCCGGTGTCACC
++
+ccc`\^`aba\b^`\FR`OOPYG[[W```[Ra_RR_\]\\P\_H_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@11100
+CGGATAACTGAAAATGCATTTTTAACGCCATGACCGTGTCTCAAGGACCCGCTGTGGAAGGGGCGCCGCAGCCAGAAGCTGGCCATGTCAGCGCG
++
+b`b_b_a\bc^Tabadaddcddd``bdaa_^aJ\^_\]\\__O[___L^\_aaa^^^UJ^BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@15663
+AGGTGAAGTGGCAGGAGGACCGCCGGAAGAAGCTCTTCAGAACTCAGGGGGAGGGGGAAAGCAGAAACCAGAAGTCCAGTGAGCAGGGGGCTGAG
++
+aaKaBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@4698
+CCAATTGGCACCCCTCTGCCTTCAGCCATTCCCTCTGGCTACTGCTCTCTGGTCGGGGCGCCTGGGCGACAGACTCTCTCCCCCCACCCCCCCGC
++
+cccc\`ccc\caccZccccc]^`LY\bL_bBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@20649
+TCTGGACTGGATCTTTAGGATGGTGGAGATGATCTGGATGTAGGACAAAAGAACCAGGCAGAAGGGTGTCATCAGAAGAACACTGCTAGACACCA
++
+eeeeeaddadacdddebeccdddadd\^abbT_]bccTac]]b]L^][]Ve[^ZaY_^_^`\\Y]^Y`BBBBBBBBBBBBBBBBBBBBBBBBBBB
+@17259
+GCCTTGTGTTGTTCCTGGCATCACCGCAGGGAGCCCTGGGGGGCCAGGCGGGCGCTGACCCTGGGCACTGCCGCGCCTGGAGGGGCTGAGCACCG
++
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@6003
+CTTCAACTCATCTTGTTATTAATACCATCAATATCCCATGAGGCTCATAAAACGAGTCTTTCTTCTTGGAAACATGACCAAGATTGGGCAAACGT
++
+fffffffffffffffffdffecfcefeffdcfdeeebbbdbccccc\db\`^aa`^Y^^^cbcbaa`bbWY^^^__S_YYR]GWY]\]]XX\_`S
+@4118
+TCAAATTGTACTGCAAAGAAGGTCCCAGCTGGTCTCTTCTGGGAGTGATCTAACTAACTTAAGCTGACCCTGTGACTGGCTGAGGATAATCCCTT
++
+dc^ddeeeeeedeee`ceceddadadddcbde_dedc_ec_a^^b\b\\]VIPZY^T^^^\L_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@18416
+GTGGGGAAGCCGAAGAAGCAGCGGAGATCGATTGTAAGAACGACGTCCATGACCAGGGTTGGTGGAGACTGCTTCTCTGCATGCGGGGGAAGGCG
++
+dddacaabdbea\d^cce\da`dd_^__`a`a`b[_^__^\^^^_BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@20115
+TGAAAAAGGAAAACATGGTAGTTTTCTTGTATGAGAGAGCCAGAGCCACCTTGGAGATTTTGTTCTCTCTGTGCGCACCAGTGATGACACAGGGG
++
+ed^eeafffaddfecdddabc^_badd`bd_ddadaa^bbcad\d\__^_\aaa_aY____aaN_\cdc\^aaYbBBBBBBBBBBBBBBBBBBBB
+@16139
+TCATCCGAAGAGTTGGCAGGCCCTGTGAATTGTGAAAACAGTATACCCACCCCTTTCCCGGAGCAGGACGCTGAATGTCCAGAGGATGCCAGACC
++
+cabacacY^c\daaddaadad^\ad_a\Y`[ZQ]Y^^OYQ^X^YT\\]U\^RRX^\YJ^BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@14123
+GATTTGGGGAAAGGAAACAATAGTTGAGTTTGGGCCACGGGAAATTCAAGATGCCTGGTATGTCAAGTCTGGCAGTTGAAGCAGCAGGGCTGGCG
++
+cccccccac^bYbbT_aa_Yb^^Ta\\^]]aaTaaaaab\b\XL`VZZV]QYYY[aa^^^^_^^BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
+@8766
+ACCTGTAAGGTCCGCTCCTGGTGGACACCCACGAAGTCCAGGGCCTCAGGCAGGAAGTTGTAGCGCAGAGTTTTGAGCAGCTGCTCCATCAGGGA
++
+fcfffffcffeffeeefdefddeecdccacddfdYd`d^\_^`\_abbc\b[ba^Y^Z_^^H^Z_^Y_Y_OKWPZR]]Z]`Z``Z^UHZ^BBBBB
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/data/maxee.fastq	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,16 @@
+@empty
+
++
+
+@ee_1
+A
++
+!
+@ee_0.8
+ACGTTGCA
++
+++++++++
+@ee_1.01
+TGGACGTTGCA
++
++5+++++++++
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/data/polya.1.fasta	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,8 @@
+>polyA
+AAACTTCAGAACAGAAAAAAAAAAAAAAAAAAAAA
+>polyAlong
+CTTAGTTCAATWTTAACCAAACTTCAGAACAGAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAA
+>polyA2
+AAACTTAACAAGAACAAGAAAAAAAAAAAAAAAAAAAAA
+>nopoly
+GAAGAGTATCTCTCTGTCCTCTTGTCCGGCGTTACAGTAATGATCG
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/data/polya.2.fasta	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,8 @@
+>polyA
+TTTTTTTTTTTTTTTTTTTTTCTGTTCTGAAGTTT
+>polyAlong
+TTTTTTTTTTTTTTTTTTTTCTTTTTTTTTTTTTTTTTTTTTCTGTTCTGAAGTTTGGTTAAWATTGAACTAAG
+>polyA2
+TTTTTTTTTTTTTTTTTTTTTCTTGTTCTTGTTAAGTTT
+>nopoly
+TCTGAAGTTTGGTTAAWATTGAACTAA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/data/simple.fasta	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,7 @@
+# a comment
+# another one
+>first_sequence
+SEQUENCE1
+>second_sequence
+SEQUEN
+CE2
Binary file test-data/cutadapt/data/simple.fasta.gz has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/data/wildcard.fa	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,4 @@
+>1
+ANGTACGTTGCATGCA
+>2
+ACGTANGTTGCATGCA
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/cutadapt/data/wildcardN.fa	Sun Dec 17 18:52:25 2023 +0000
@@ -0,0 +1,6 @@
+>perfect
+TTTGGGGGGG
+>withN
+TTTGGNGGGG
+>1mism
+TTTGGGGCGG
--- a/test-data/cutadapt_rest.json	Fri May 19 21:42:14 2023 +0000
+++ b/test-data/cutadapt_rest.json	Sun Dec 17 18:52:25 2023 +0000
@@ -46,6 +46,9 @@
     "quality_trimmed": null,
     "quality_trimmed_read1": null,
     "quality_trimmed_read2": null,
+    "poly_a_trimmed": null,
+    "poly_a_trimmed_read1": null,
+    "poly_a_trimmed_read2": null,
     "output": 35,
     "output_read1": 35,
     "output_read2": null
@@ -81,5 +84,7 @@
       }
     }
   ],
-  "adapters_read2": null
+  "adapters_read2": null,
+  "poly_a_trimmed_read1": null,
+  "poly_a_trimmed_read2": null
 }