.trimFastq1 <-
    function(file1, dest1, file2=character(), dest2=character(),
             k, a, halfwidth, minLength=0, adapters=DNAStringSet(),
             verbose=TRUE)
{
    paired <- length(file2) != 0
    ## open input stream
    stream1 <- FastqStreamer(file1, 500000)
    on.exit(close(stream1))
    if (paired) {
        stream2 <- open(FastqStreamer(file2, 500000))
        on.exit(close(stream2))
    }
    n <- 0
    
    repeat {
        ## input chunk
        fq1 <- yield(stream1)
        if (length(fq1) == 0)
            break
        if (length(file2))
            fq2 <- yield(stream2)

        n <- n + length(fq1)
        if (verbose)
            message(n)
        
        if (is.numeric(a)) {
            enc <- encoding(quality(fq1))
            a <- names(enc)[a==enc]
        }
        fq1 <- trimTailw(fq1, k, a, halfwidth)
        idx <- width(fq1) > minLength
        if (paired) {
            fq2 <- trimTailw(fq2, k, a, halfwidth)
            idx <- idx & (width(fq2) > minLength)
        }

        writeFastq(fq1[idx], dest1, "a")
        if (paired)
            writeFastq(fq2[idx], dest2, "a")
    }
}

trimFastq <-
    function(files1, files2=character(), destination,
             k=2, a=20, halfwidth=2, minLength=0, adapters=DNAStringSet(),
             verbose=TRUE)
    ## Default: trim as soon as 2 of 5 nucleotides has quality
    ## encoding less phred score 20
{
    dest1 <- file.path(destination,
                       sub(".fastq", "_trimmed.fastq", basename(files1)))
    dest2 <- file.path(destination,
                       sub(".fastq", "_trimmed.fastq", basename(files2)))

    if (any(i <- file.exists(c(dest1, dest2))))
        stop("destination file(s) exist:\n  ",
             paste(c(dest1, dest2)[i], collapse="\n  "))

    if (length(files2))
        Map(.trimFastq1, files1, dest1, files2, dest2,
            MoreArgs=list(k=k, a=a, halfwidth=halfwidth, minLength=minLength,
              adapters=adapters, verbose=verbose))
    else
        Map(.trimFastq1, files1, dest1,
            MoreArgs=list(k=k, a=a, halfwidth=halfwidth, minLength=minLength,
              adapters=adapters, verbose=verbose))
    
    c(dest1, dest2)
}
