Trimmomatic failing to cut known adapter
2
1
Entering edit mode
3.0 years ago
maxrwjones ▴ 60

Hi all,

Usually get on well with Trimmomatic but am having issues removing adapters from some paired-end RNA-seq data. Here's my process so far:

1) Put together a PE adapter fasta for the adapters described by the sequencing company; ran trimmomatic; no reads dropped.

2) Ran Trim_galore! to automatically detect adapters. It detected the Illumina sequence AGATCGGAAGAGC in ~30% of reads.

3) I grepped for this sequence in the raw FASTQs (and used flag -B 1 to also retrieve the metadata line). Sure enough, I could see this sequence in the grepped fastq entries, plus 20 bp following that were different for Read 1's vs Read 2's. (Images 1 and 3 respectively, see highlighted regions for an example.)

4) I searched the Illumina adapters PDF for these sequences, and they turn out to be a perfect match for the "IDT for Illumina TruSeq DNA and RNA UD Indexes" (see image 2). I then confirmed with the sequencing company that this was what they had in fact used - yes, the ones they initially sent me were wrong. Great, back to trimmomatic then!

5) Ran trimmomatic looking for these adapters (which I had confirmed with my own eyes were present in at least a handful of reads - hopefully you can confirm this for yourself using the screenshots provided). Zero reads dropped. I tried every combination of the adapter sequences I could think of, including complements with non-complements, read 2 adapters taking the place of read 1 adapters, etc, etc. Still zero reads dropped. (See below for a list of all pairs of adapter sequences I submitted to trimmomatic.)

What am I doing wrong? I will likely just accept the results of trim_galore and move on, but this is driving me crazy as I can't see any reason why it isn't working.

ADAPTER SEQUENCES TRIALLED: (formatting being mucked around by BioStars, the "Prefix.../1" was in fact on a separate line to the nucleotides and there were angle brackets (greater-than-signs) at the start of each "Prefix..." line.)

>PrefixIllumina1/1
AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
>PrefixIllumina1/2
AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT
>PrefixIllumina2/1
AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT
>PrefixIllumina2/2
AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
>PrefixIllumina3/1
TCTAGCCTTCTCGTGTGCAGACTTGAGGTCAGT
>PrefixIllumina3/2
TCTAGCCTTCTCGCAGCACATCCCTTTCTCACA
>PrefixIllumina4/1
TCTAGCCTTCTCGCAGCACATCCCTTTCTCACA
>PrefixIllumina4/2
TCTAGCCTTCTCGTGTGCAGACTTGAGGTCAGT
>PrefixIlluminaOne/1
AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
>PrefixIlluminaOne/2
AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT
>PrefixIlluminaTwo/1
AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
>PrefixIlluminaTwo/2
TCTAGCCTTCTCGCAGCACATCCCTTTCTCACA
>PrefixIlluminaThree/1
TCTAGCCTTCTCGTGTGCAGACTTGAGGTCAGT
>PrefixIlluminaThree/2
TCTAGCCTTCTCGCAGCACATCCCTTTCTCACA
>PrefixIlluminaFour/1
TCTAGCCTTCTCGTGTGCAGACTTGAGGTCAGT
>PrefixIlluminaFour/2
AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT`

Screenshot of example read 1's Illumina adapter PDF screenshot Screenshot of example read 2's

trimmomatic • 5.9k views
ADD COMMENT
1
Entering edit mode

If you are willing to try an alternate program I suggest using bbduk from BBMap suite or fastp. A guide to use bbduk is available.

ADD REPLY
0
Entering edit mode

Thank you GenoMax, I may well give it a try if this banging-head-against-wall issue persists!

ADD REPLY
0
Entering edit mode

Simply use the adapters.fa file provided in the bbmap in resource directory as source for adapters.

ADD REPLY
1
Entering edit mode

Hi all,

Thanks so much for all your help. I've been doing some more testing and have figured out a few things / learned them from your posts: 1) Originally trimmomatic wasn't reporting any dropped reads because none should have been dropped: they were trimmed, but were still >0 bp so were retained 2) However, even when I included a MINLEN:150 function in trimmomatic (which should make dropped reads = trimmed reads), I was still able to grep out many tens of thousands of reads with obvious adapter contamination. 3) GenoMax was able to remove these using bbduk, while Istvan was able to remove these using a single simple adapter file in trimmomatic 4) I have since also been able to remove these using trimmomatic in palindromic mode. I read in the trimmomatic manual that "adapter sequences are 'in silico ligated' onto the start of the reads" for palindrome mode. As a result, one has to provide trimmomatic with the reverse complement of the adapter contamination sequences that one can see in the raw fastq. This is backed up by comparing the adapter fastas on trimmomatic's GitHub page with those found in the Illumina adapters PDF - they are indeed reverse complements of one another. 5) So, I now have trimmomatic palindromic trimming working. For thoroughness, I also ran trim_galore, fastp, and bbduk... I assumed they would all come out with vaguely similar answers now. Absolutely not...

  • trimmomatic: 1.46% reads trimmed
  • trim_galore: 31.0% reads trimmed 0.6% bases trimmed
  • fastp: 2.04% reads trimmed, 1.32% bases trimmed
  • bbduk: 45.74% reads trimmed, 28.42% bases trimmed

So one problem down and another has cropped up. What could be causing these drastic differences?

Supplied or detected adapters for each software:

trimmomatic:
>PrefixPE/1
TACACTCTTTCCCTACACGACGCTCTTCCGATCT
>PrefixPE/2
GTGACTGGAGTTCAGACGTGTGCTCTTCCGATCT

trim_galore:
Nothing supplied, software auto-detected
AGATCGGAAGAGC
and used this for both reads

fastp:
Nothing supplied, software auto-detected
Read 1: AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
Read 2: AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT

bbduk:
Supplied with the common sequence
AGATCGGAAGAGC
as per GenoMax's example
ADD REPLY
2
Entering edit mode

Important details:

  1. Do NOT use the palindromic mode in Trimmomatic, I never fully understood what that does and how it affects the process. To make things even more confusing the palindromic mode is not even a parameter that is visible at invocation. The palindromic mode automatically triggers based on the presence of / in the adapter name!
  2. All other tools cut adapters in the "old fashioned" way
  3. You do not need to include the reverse of the adapter, the adapter is not reverse complemented!
  4. When comparing output use the same adapter sequences in all cases (evidently that will make a huge difference)
  5. Do not rely on autodetection, that's only useful for sanity check
  6. Only include the adapter for the common region (if such exists), no need to put the whole adapter there

In general, for standard Illumina adapters usually, it is sufficient to list the beginning of the adapter sequence, it will trim the rest accordingly:

>adapter
AGATCGGAAGAGC

if you use this adapter then all tools should produce similar results (when invoked to operated in a similar fashion)

ADD REPLY
0
Entering edit mode

Hi Istvan,

Thanks for your time on all parts of this query. Your advice above is really appreciated, I'll make sure in particular to avoid mixing different adapter sequences when comparing tools.

ADD REPLY
1
Entering edit mode

To make this a fair comparison you need to supply the same target sequence for all software so you may want to re-do all results using the trimmomatic oligos.

BBduk (and other programs) have many options that can affect end-result e.g. if you have paired end data you need to use tbo tpe options to remove contaminants as small as one bp. There are default values for all parameters that may not always be appropriate but are going to be applied when you run the program. This can affect end results.

I have a feeling you are making this more complicated that it really is.

As you may have realized by now, there is a core sequence that is common for all illumina multiplexed adapters. Once trimming programs find this sequence they will trim all sequence to the 3'-end of that core.

With bbduk use the following command:

bbduk.sh -Xmx4g threads=N (replace with num cores) in1=R1.fq.gz in2=R2.fq.gz out1=clean_R1.fq.gz out2=clean_R2.fq.fz ref=adapters.fa (use the file in resources dir) k=21 ktrim=r tbo tpe 

OR

if you want to provide adapter sequences

bbduk.sh -Xmx4g threads=N (replace with number of cores) in1=R1.fq.gz in2=R2.fq.gz out1=clean_R1.fq.gz out2=clean_R2.fq.gz literal=TACACTCTTTCCCTACACGACGCTCTTCCGATCT,GTGACTGGAGTTCAGACGTGTGCTCTTCCGATCT k=21 ktrim=r tbo tpe 
ADD REPLY
0
Entering edit mode

Hi GenoMax,

You're right, I'm realising there are a lot of other parameters and filtering steps 'under the hood' that are obfuscating and invalidating the results of my tests.

With your suggested code here I got a much more sensible answer from bbduk. It seems the k=N parameter has quite a large effect on the result!

Still unsure whether I'll go for fastp or bbduk in the end, but I'm a little disillusioned with trimmomatic now!

ADD REPLY
0
Entering edit mode

Provide complete command line you are using.

ADD REPLY
0
Entering edit mode

Trimmomatic not called using usual Java command as it has been set up on my institute's cluster to be called like a bash command. Have previously used this installation of trimmomatic and has worked a charm. It's containerised in Singularity so cannot have been tampered with since I last used it. ("illumina_adapters2.fa" contained the first 8 adapters (4 pairs) listed above, I also ran this command again using a second file called "illumina_adapters3.fa" that contained the remaining adapter pairs listed above.)

trimmomatic PE -threads 4 \
/jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/raw_FASTQs//"$sample_prefix"_1.fq.gz \
/jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/raw_FASTQs//"$sample_prefix"_2.fq.gz \
-baseout /jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/trimmed_FASTQs//"$sample_prefix".fq.gz \
ILLUMINACLIP:/jic/scratch/groups/Cristobal-Uauy/mjones/scripts/illumina_adapters2.fa:2:30:10:1:true
echo ""
echo "Finished trimming $sample_prefix"
echo ""
echo ""
ADD REPLY
0
Entering edit mode

Sorry for the awful formatting... I can't seem to get code to wrap nicely on here.

ADD REPLY
1
Entering edit mode

Use the 101010 button after highlighting text you want to format as code. I have done it for you now.

ADD REPLY
0
Entering edit mode

This was the output from trimmomatic:

TrimmomaticPE: Started with arguments:
 -threads 4 /jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/raw_FASTQs//BD10_2_R_1.fq.gz /jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/raw_FASTQs//BD10_2_R_2.fq.gz -baseout /jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/trimmed_FASTQs//BD10_2_R.fq.gz ILLUMINACLIP:/jic/scratch/groups/Cristobal-Uauy/mjones/scripts/illumina_adapters3.fa:2:30:10:1:true
Using templated Output files: /jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/trimmed_FASTQs/BD10_2_R_1P.fq.gz /jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/trimmed_FASTQs/BD10_2_R_1U.fq.gz /jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/trimmed_FASTQs/BD10_2_R_2P.fq.gz /jic/scratch/groups/Cristobal-Uauy/mjones/spike_dev_timecourse_analyses/RNAseq_timecourse/trimmed_FASTQs/BD10_2_R_2U.fq.gz
Using PrefixPair: 'AGATCGGAAGAGCACACGTCTGAACTCCAGTCA' and 'AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT'
Using PrefixPair: 'AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT' and 'AGATCGGAAGAGCACACGTCTGAACTCCAGTCA'
Using PrefixPair: 'TCTAGCCTTCTCGTGTGCAGACTTGAGGTCAGT' and 'TCTAGCCTTCTCGCAGCACATCCCTTTCTCACA'
Using PrefixPair: 'TCTAGCCTTCTCGCAGCACATCCCTTTCTCACA' and 'TCTAGCCTTCTCGTGTGCAGACTTGAGGTCAGT'
ILLUMINACLIP: Using 4 prefix pairs, 0 forward/reverse sequences, 0 forward only sequences, 0 reverse only sequences
Quality encoding detected as phred33
Input Read Pairs: 58955635 Both Surviving: 58955635 (100.00%) Forward Only Surviving: 0 (0.00%) Reverse Only Surviving: 0 (0.00%) Dropped: 0 (0.00%)
TrimmomaticPE: Completed successfully
ADD REPLY
3
Entering edit mode
3.0 years ago

I think you are overcomplicating things, make a simple adapter file like so:

>adapter
AGATCGGAAGAGCACACGTCTGAACTCCAGTCAC

then cut with that.

Trimmomatic has some additional features and behaviors called palindromic trimming and I think naming your reads with trailing /1 and /2 triggers that behavior.

ADD COMMENT
0
Entering edit mode

Hi Istvan,

Thanks for your answer. I'm aware of palindromic trimming and it is a feature I would like to use. Are you sure palindromic trimming can be called in the manner you suggest?

This from the trimmomatic manual says nothing about naming the reads with trailing /1 and /2 as you suggest:

Providing sequences for palindrome trimming: Naming of the sequences determines how they are used. For 'Palindrome' clipping, a matched pair (or multiple matched pairs) of adapter sequences must be provided. The sequence names should both start with 'Prefix', and end in '/1' for the forward adapter and '/2' for the reverse adapter. The part of the name between "Prefix" and "/1" or "/2" must match exactly within each pair.

This suggests that using a simple adapter file will not engage the palindromic mode. But if you know otherwise I can try it.

ADD REPLY
0
Entering edit mode

I ended up trying your method of using simple adapters, but not much more luck unfortunately. I used this as the adapter fasta:

>adapter1
AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
>adapter2
AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT

Where adapter 1 is what I expect in read 1 adapter read-throughs and adapter 2 is what I expect in read 2 adapter read-throughs.

This returned <100 reads dropped though I know that there are >500,000 reads in each of read 1 and read 2 files containing the sequence AGATCGGAAGAGC, i.e. the start of the both adapters, as I grepped for this. So, so confused right now!

ADD REPLY
1
Entering edit mode

let's make sure we are talking about the same thing, the reads with adapters should not be dropped but trimmed.

In general, you should not expect reads dropping at all. The length of the reads will change. I just tried the adapter sequence on your test data and it works as it should:

seqkit stats test.fq

prints:

file     format  type  num_seqs  sum_len  min_len  avg_len  max_len
test.fq  FASTQ   DNA          4      600      150      150      150

let's run trimmomatic on your test data:

trimmomatic SE test.fq output.fq ILLUMINACLIP:adapter.fa:2:30:5

reports zero reads dropped. But the reads were indeed trimmed:

seqkit stats output.fq

and that prints:

file       format  type  num_seqs  sum_len  min_len  avg_len  max_len
output.fq  FASTQ   DNA          4      461      105    115.3      131

see how the sum_len was reduced and the read lengths are different?

ADD REPLY
0
Entering edit mode

can you post few reads that were not trimmed by trimmomatic?

ADD REPLY
0
Entering edit mode

Done, see below!

ADD REPLY
0
Entering edit mode

I've realised that part of the problem is that trimmomatic only reports "dropped" reads - it does not state how many reads were trimmed. So I have added a MINLEN:150 command so that any reads that are trimmed by even 1 bp are dropped.

This helped somewhat, I now get 514,033 reads dropped. However, there are still more reads containing adapter contamination. If I grep the trimmed FASTA for AGATCGGAAGAGC there are still 307,326 sequences remaining. By eye, the majority of these continue on into the expected adapter sequence (given in "adapter 1" above) so are not just random occurrences of the grepped 13-mer.

Some example untrimmed reads that I think should have been trimmed:

@A00709:235:HK737DSX2:3:1101:1407:4742 1:N:0:ACGGTAGT+ATTGCGGA
CTGGGCTCCCTAATCTAACTTTCTTCTTAGGCTGATCATCTTCTTCATGATTTACAAGTAGCCTTCCACGTTTTTGCCCCACCTTAAGGGCCCCATCAATTCTGAAGATCGGAAGAGCACACGTCTGAACTCCAGTCACACGGTAGTATC
--
@A00709:235:HK737DSX2:3:1101:25672:4961 1:N:0:ACGGTAGT+ATTGCGGA
GGAAGCTTGTCAATAGCAGTTTTGCTGATCTGCAAAAGCCACAGATGGAGCTGGATGGAAAGGCGTGCGCTGCTGTTGGTCAGAGTGGGCTGATGGCACTCTATGACATGTTGTTTAGATCGGAAGAGCACACGTCTGAACTCCAGTCAC
--
@A00709:235:HK737DSX2:3:1101:7889:5071 1:N:0:ACGGTAGT+ATTGCGGA
ATTTACTCTCGGTGATGGAGTCATCAAGAATACCTGCTGGCCCCAGTGTGTCCCACCATTCTCATCTGGGGCTGTATTCAATTCAACTTCCTCAACTGCAGGGTTTTGCAGATCGGAAGAGCACACGTCTGAACTCCAGTCACACGGTAG
--
@A00709:235:HK737DSX2:3:1101:27760:5259 1:N:0:ACGGTAGT+ATTGCGGA
TCAGGTTCTGGACTACCATCATTCTCACTGAGTGCTCGCACATTCGAATGCAACGGCCCAGCCAAGTTATTGAATGAAATGTTAAAAACAGACGGTGATGATACTGAAGGGGTAAGATCGGCAATGTTTCCAGATCGGAAGAGCACACGT
--
@A00709:235:HK737DSX2:3:1101:30581:5259 1:N:0:ACGGTAGT+ATTGCGGA
CACGCCGTCTCCGAGGGCACCAAGGCTGTCACCAAGTTCACCTCCTCCTGAGTCTCGTAGTTAGCTGTTTGGGTGTGTTTGTGGCCGTGTTATCGTGAGATCGGAAGAGCACACGTCTGAACTCCAGTCACACGGTAGTATCGCGGGTGG
ADD REPLY
1
Entering edit mode

Grepping for that short a sequence may not always be fool proof. If you used bbduk it will clearly tell you what happened to the reads as they got trimmed. I converted your example reads into fasta for ease but same will work with fastq data.

$ more test.fa
>A00709:235:HK737DSX2:3:1101:1407:4742 1:N:0:ACGGTAGT+ATTGCGGA
CTGGGCTCCCTAATCTAACTTTCTTCTTAGGCTGATCATCTTCTTCATGATTTACAAGTAGCCTTCCACGTTTTTGCCCCACCTTAAGGGCCCCATCAATTCTGAAGATCGGAAGAGCACACGTCTGAACTCCAGTCACACGGTAGTATC
>A00709:235:HK737DSX2:3:1101:25672:4961 1:N:0:ACGGTAGT+ATTGCGGA
GGAAGCTTGTCAATAGCAGTTTTGCTGATCTGCAAAAGCCACAGATGGAGCTGGATGGAAAGGCGTGCGCTGCTGTTGGTCAGAGTGGGCTGATGGCACTCTATGACATGTTGTTTAGATCGGAAGAGCACACGTCTGAACTCCAGTCAC
>A00709:235:HK737DSX2:3:1101:7889:5071 1:N:0:ACGGTAGT+ATTGCGGA
ATTTACTCTCGGTGATGGAGTCATCAAGAATACCTGCTGGCCCCAGTGTGTCCCACCATTCTCATCTGGGGCTGTATTCAATTCAACTTCCTCAACTGCAGGGTTTTGCAGATCGGAAGAGCACACGTCTGAACTCCAGTCACACGGTAG
>A00709:235:HK737DSX2:3:1101:27760:5259 1:N:0:ACGGTAGT+ATTGCGGA
TCAGGTTCTGGACTACCATCATTCTCACTGAGTGCTCGCACATTCGAATGCAACGGCCCAGCCAAGTTATTGAATGAAATGTTAAAAACAGACGGTGATGATACTGAAGGGGTAAGATCGGCAATGTTTCCAGATCGGAAGAGCACACGT

$ bbduk.sh -Xmx2g in=test.fa literal=AGATCGGAAGAGC k=7 ktrim=r out=stdout.fa fastawrap=120

Version 38.35

Initial:
Memory: max=2147m, total=2147m, free=2129m, used=18m

Added 7 kmers; time:    0.002 seconds.
Memory: max=2147m, total=2147m, free=2127m, used=20m

Input is being processed as unpaired
Started output streams: 0.007 seconds.
>A00709:235:HK737DSX2:3:1101:1407:4742 1:N:0:ACGGTAGT+ATTGCGGA
CTGGGCTCCCTAATCTAACTTTCTTCTTAGGCTGATCATCTTCTTCATGATTTACAAGTAGCCTTCCACGTTTTTGCCCCACCTTAAGGGCCCCATCAATTCTGA
>A00709:235:HK737DSX2:3:1101:25672:4961 1:N:0:ACGGTAGT+ATTGCGGA
GGAAGCTTGTCAATAGCAGTTTTGCTGATCTGCAAAAGCCACAGATGGAGCTGGATGGAAAGGCGTGCGCTGCTGTTGGTCAGAGTGGGCTGATGGCACTCTATGACATGTTGTTT
>A00709:235:HK737DSX2:3:1101:7889:5071 1:N:0:ACGGTAGT+ATTGCGGA
ATTTACTCTCGGTGATGGAGTCATCAAGAATACCTGCTGGCCCCAGTGTGTCCCACCATTCTCATCTGGGGCTGTATTCAATTCAACTTCCTCAACTGCAGGGTTTTGC
>A00709:235:HK737DSX2:3:1101:27760:5259 1:N:0:ACGGTAGT+ATTGCGGA
TCAGGTTCTGGACTACCATCATTCTCACTGAGTGCTCGCACATTCGAATGCAACGGCCCAGCCAAGTTATTGAATGAAATGTTAAAAACAGACGGTGATGATACTGAAGGGGTA
Processing time:        0.004 seconds.

Input:                      4 reads         600 bases.
KTrimmed:                   4 reads (100.00%)   156 bases (26.00%)
Total Removed:              0 reads (0.00%)     156 bases (26.00%)
Result:                     4 reads (100.00%)   444 bases (74.00%)

Time:                           0.014 seconds.
Reads Processed:           4    0.29k reads/sec
Bases Processed:         600    0.04m bases/sec
ADD REPLY
0
Entering edit mode
2.0 years ago
Oliver • 0

I want to add, that trimmomatic also takes in a scoring threshold (namely the simpleClipThreshold in the Step options ILLUMINACLIP), which causes Trimmomatic to only accept matching adaptors, where the alignment score passes this limit.

From the Trimmomatic documentation:

simpleClipThreshold: specifies how accurate the match between any adapter etc. sequence must be against a read.

The thresholds used are a simplified log-likelihood approach. Each matching base adds just over 0.6, while each mismatch reduces the alignment score by Q/10. Therefore, a perfect match of a 12 base sequence will score just over 7, while 25 bases are needed to score 15. As such we recommend values between 7 - 15 for this parameter. For palindromic matches, a longer alignment is possible - therefore this threshold can be higher, in the range of 30. The 'seed mismatch' parameter is used to make alignments more efficient, specifying the maximum base mismatch count in the 'seed' (16 bases). Typical values here are 1 or 2.

So when I was using

>Illumina_Universal_Adaptor
AGATCGGAAGAGC

as adaptor, I had to set this threshold to 7 or lower, in order to recognize this adaptor sequence (since 13 * 0.6 = 7.8). Playing around with this value finally enabled trimmomatic in my case, to remove all Illumina-Adaptors.

ADD COMMENT

Login before adding your answer.

Traffic: 1764 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6