# motifStack Vignette

#### Jianhong Ou, Michael Brodsky, Lihua Julie Zhu

#### 27 April 2020

Abstract

The motifStack package is designed for graphic representation of multiple motifs with different similarity scores. It works with both DNA/RNA sequence motif, affinity logo and amino acid sequence motif. In addition, it provides the flexibility for users to customize the graphic parameters such as the font type and symbol colors.

# Introduction

A sequence logo, based on information theory, has been widely used as a graphical representation of sequence conservation (aka motif) in multiple amino acid or nucleic acid sequences. Sequence motif represents conserved characteristics such as DNA binding sites, where transcription factors bind, and catalytic sites in enzymes. Although many tools, such as seqlogo1, have been developed to create sequence motif and to represent it as individual sequence logo, software tools for depicting the relationship among multiple sequence motifs are still lacking. We developed a flexible and powerful open-source R/Bioconductor package, motifStack, for visualization of the alignment of multiple sequence motifs.

# Examples of using motifStack

## plot a DNA sequence logo with different fonts and colors

Users can select different fonts and colors to draw the sequence logo.

    suppressPackageStartupMessages(library(motifStack))
    pcm <- read.table(file.path(find.package("motifStack"),
                                "extdata", "bin_SOLEXA.pcm"))
    pcm <- pcm[,3:ncol(pcm)]
    rownames(pcm) <- c("A","C","G","T")
    motif <- new("pcm", mat=as.matrix(pcm), name="bin_SOLEXA")
    ##pfm object
    #motif <- pcm2pfm(pcm)
    #motif <- new("pfm", mat=motif, name="bin_SOLEXA")
    plot(motif)

Plot a DNA sequence logo with different fonts and colors

    #plot the logo with same height
    plot(motif, ic.scale=FALSE, ylab="probability")

Plot a DNA sequence logo with different fonts and colors

    #try a different font
    plot(motif, font="mono,Courier", fontface="plain") # fontface can be 1=plain, 2=bold, 3=italic, 4=bold italic

Plot a DNA sequence logo with different fonts and colors

    #try a different font and a different color group
    motif@color <- colorset(colorScheme='basepairing')
    plot(motif,font="Times")

Plot a DNA sequence logo with different fonts and colors

## plot sequence logo with markers

If you assign markers slot by a list of `marker` object, markers can be plotted in the figure. There are three type of markers, “rect”, “line” and “text”.

    markerRect <- new("marker", type="rect", start=6, stop=7, gp=gpar(lty=2, fill=NA, col="orange"))
    markerLine <- new("marker", type="line", start=2, stop=7, gp=gpar(lwd=2, col="red"))
    markerText <- new("marker", type="text", start=c(1, 5),
                      label=c("*", "core"), gp=gpar(cex=2, col="red"))
    motif <- new("pcm", mat=as.matrix(pcm), name="bin_SOLEXA",
                 markers=c(markerRect, markerLine, markerText))
    plot(motif)

Plot a DNA sequence logo with markers

## plot a RNA sequence logo

To plot a RNA sequence logo, you only need to change the rowname of the matrix from “T” to “U” as follows.

    rna <- pcm
    rownames(rna)[4] <- "U"
    motif <- new("pcm", mat=as.matrix(rna), name="RNA_motif")
    plot(motif)

Plot an RNA sequence logo

## plot an amino acid sequence logo

Given that motifStack allows to use any letters as symbols, it can also be used to draw amino acid sequence logos.

    library(motifStack)
    protein<-read.table(file.path(find.package("motifStack"),"extdata","cap.txt"))
    protein<-t(protein[,1:20])
    motif<-pcm2pfm(protein)
    motif<-new("pfm", mat=motif, name="CAP",
                color=colorset(alphabet="AA",colorScheme="chemistry"))
    plot(motif)

Plot an sequence logo with any symbols as you want such as amino acid sequence logo

## plot an affinity logo

It can also be used to draw affinity logos given a position specific affinity matrix (PSAM) as described by Foat et al. 2.

    library(motifStack)
    motif<-matrix(
      c(
        .846, .631, .593, .000, .000, .000, .434, .410, 1.00, .655, .284, .000, .000, .771, .640, .961,
        .625, .679, .773, 1.00, 1.00, .000, .573, .238, .397, 1.00, 1.00, .000, .298, 1.00, 1.00, .996,
        1.00, 1.00, 1.00, .228, .000, 1.00, 1.00, .597, .622, .630, .000, 1.00, 1.00, .871, .617, 1.00,
        .701, .513, .658, .000, .000, .247, .542, 1.00, .718, .686, .000, .000, .000, .595, .437, .970
      ), nrow=4, byrow = TRUE)
    rownames(motif) <- c("A", "C", "G", "T")
    motif<-new("psam", mat=motif, name="affinity logo",
               markers=list(new("marker", type="rect",
                                start=c(4, 11), stop=c(6, 13),
                                gp=gpar(col="#009E73", fill=NA, lty=2))))
    plot(motif)

Plot an affinity logo

## plot sequence logo stack

To show multiple motifs on the same canvas as a sequence logo stack, the distance of motifs need to be calculated first. By default, MotIV3::`motifDistances` ( R implementation of STAMP4) is used to calculate the distance. After alignment, users can use `plotMotifLogoStack`, `plotMotifLogoStackWithTree` or `plotMotifStackWithRadialPhylog` to draw sequence logos in different layouts. To make it easy to use, we integrated different functionalities into one workflow function named as `motifStack`.

    suppressPackageStartupMessages(library(motifStack))
    #####Input#####
    motifs<-importMatrix(dir(file.path(find.package("motifStack"), "extdata"),"pcm$", full.names = TRUE))

    ## plot stacks
    motifStack(motifs, layout="stack", ncex=1.0)

Plot motifs with sequence logo stack style

    motif2 <- motif
    motif2$mat <- motif$mat[, 5:12]
    motif2$name <- "logo2"
    psamMotifs <- list(motif, motif2)
    motifStack(psamMotifs)

Plot affinity logos with sequence logo stack style

    ## plot stacks with hierarchical tree
    motifStack(motifs, layout="tree")

Sequence logo stack with hierarchical cluster tree

    ## When the number of motifs is too much to be shown in a vertical stack,
    ## motifStack can draw them in a radial style.
    ## random sample from MotifDb
    library("MotifDb")

    ## See system.file("LICENSE", package="MotifDb") for use restrictions.

    matrix.fly <- query(MotifDb, "Dmelanogaster")
    motifs2 <- as.list(matrix.fly)
    ## use data from FlyFactorSurvey
    motifs2 <- motifs2[grepl("Dmelanogaster\\-FlyFactorSurvey\\-",
                             names(motifs2))]
    ## format the names
    names(motifs2) <- gsub("Dmelanogaster_FlyFactorSurvey_", "",
                           gsub("_FBgn\\d+$", "",
                                gsub("[^a-zA-Z0-9]","_",
                                     gsub("(_\\d+)+$", "", names(motifs2)))))
    motifs2 <- motifs2[unique(names(motifs2))]
    pfms <- sample(motifs2, 30)
    ## creat a list of object of pfm
    motifs2 <- lapply(names(pfms),
                      function(.ele, pfms){new("pfm",mat=pfms[[.ele]], name=.ele)}
                      ,pfms)
    ## trim the motifs
    motifs2 <- lapply(motifs2, trimMotif, t=0.4)
    ## setting colors
    library(RColorBrewer)
    color <- brewer.pal(10, "Set3")
    ## plot logo stack with radial style
    motifStack(motifs2, layout="radialPhylog",
               circle=0.3, cleaves = 0.2,
               clabel.leaves = 0.5,
               col.bg=rep(color, each=3), col.bg.alpha=0.3,
               col.leaves=rep(color, each=3),
               col.inner.label.circle=rep(color, each=3),
               inner.label.circle.width=0.05,
               col.outer.label.circle=rep(color, each=3),
               outer.label.circle.width=0.02,
               circle.motif=1.2,
               angle=350)

    ## Warning in polygon(c(P$x, 0), c(P$y, 0), border = bgcol[i], col = bgcol[i]):
    ## semi-transparency is not supported on this device: reported only once per page

Plot motifs in a radial style when the number of motifs is too much to be shown in a vertical stack

## plot a sequence logo cloud

We can also plot a sequence logo cloud for DNA motifs.

    ## assign groups for motifs
    groups <- rep(paste("group",1:5,sep=""), each=10)
    names(groups) <- names(pfms)
    ## assign group colors
    group.col <- brewer.pal(5, "Set3")
    names(group.col)<-paste("group",1:5,sep="")
    ## use MotIV to calculate the distances of motifs
    jaspar.scores <- MotIV::readDBScores(file.path(find.package("MotIV"),
                                                   "extdata",
                                                   "jaspar2010_PCC_SWU.scores"))
    d <- MotIV::motifDistances(lapply(pfms, pfm2pwm))
    hc <- MotIV::motifHclust(d, method="average")
    ## convert the hclust to phylog object
    phylog <- hclust2phylog(hc)
    ## reorder the pfms by the order of hclust
    leaves <- names(phylog$leaves)
    pfms <- pfms[leaves]
    ## create a list of pfm objects
    pfms <- lapply(names(pfms), function(.ele, pfms){
                                    new("pfm",mat=pfms[[.ele]], name=.ele)}
                   ,pfms)
    ## extract the motif signatures
    motifSig <- motifSignature(pfms, phylog, groupDistance=0.01, min.freq=1)
    ## draw the motifs with a tag-cloud style.
    motifCloud(motifSig, scale=c(6, .5),
               layout="rectangles",
               group.col=group.col,
               groups=groups,
               draw.legend=TRUE)

Sequence logo cloud with rectangle packing layout

## plot grouped sequence logo

Grouped sequence logo can also be plotted in radial phylogeny tree style.

    ## get the signatures from object of motifSignature
    sig <- signatures(motifSig)
    ## set the inner-circle color for each signature
    gpCol <- sigColor(motifSig)
    ## plot the logo stack with radial style.
    plotMotifStackWithRadialPhylog(phylog=phylog, pfms=sig,
                                  circle=0.4, cleaves = 0.3,
                                  clabel.leaves = 0.5,
                                  col.bg=rep(color, each=3), col.bg.alpha=0.3,
                                  col.leaves=rep(rev(color), each=3),
                                  col.inner.label.circle=gpCol,
                                  inner.label.circle.width=0.03,
                                  angle=350, circle.motif=1.2,
                                  motifScale="logarithmic")

    ## Warning in polygon(c(P$x, 0), c(P$y, 0), border = bgcol[i], col = bgcol[i]):
    ## semi-transparency is not supported on this device: reported only once per page

Grouped sequence logo with radialPhylog style layout

## motifCircos

We can also plot it with circos style. In circos style, we can plot two group of motifs and with multiple color rings.

    ## plot the logo stack with cirsoc style.
    motifCircos(phylog=phylog, pfms=pfms, pfms2=sig,
                col.tree.bg=rep(color, each=5), col.tree.bg.alpha=0.3,
                col.leaves=rep(rev(color), each=5),
                col.inner.label.circle=gpCol,
                inner.label.circle.width=0.03,
                col.outer.label.circle=gpCol,
                outer.label.circle.width=0.03,
                r.rings=c(0.02, 0.03, 0.04),
                col.rings=list(sample(colors(), 30),
                               sample(colors(), 30),
                               sample(colors(), 30)),
                angle=350, motifScale="logarithmic")

    ## Warning in polygon(P$x, P$y, border = bgcol[i], col = bgcol[i]): semi-
    ## transparency is not supported on this device: reported only once per page

Grouped sequence logo with circos style layout

## motifPiles

We can also plot the motifs in pile style. In pile style, we can plot two group of motifs with multiple types of annotation, for example heatmap. The col.anno parameter should be set as a named list.

    ## plot the logo stack with heatmap.
    df <- data.frame(A=runif(n = 30), B=runif(n = 30), C=runif(n = 30), D=runif(n = 30))
    map2col <- function(x, pal){
      rg <- range(x)
      pal[findInterval(x, seq(rg[1], rg[2], length.out = length(pal)+1),
                       all.inside = TRUE)]
    }
    dl <- lapply(df, map2col, pal=heat.colors(10))
    motifPiles(phylog=phylog, pfms=pfms,
                col.tree=rep(color, each=5),
                col.leaves=rep(rev(color), each=5),
                col.pfms2=gpCol,
                r.anno=rep(0.02, length(dl)),
                col.anno=dl,
                motifScale="logarithmic",
                plotIndex=TRUE,
                groupDistance=0.01)

Grouped sequence logo with a heatmap

# plot motifs with d3.js

Interactive plot can be generated using `browseMotifs` function which leverages the d3.js library. All motifs on the plot are draggable and the plot can be easily exported as a Scalable Vector Graphics (SVG) file.

    browseMotifs(pfms = pfms, phylog = phylog, layout="tree", yaxis = FALSE, baseWidth=6, baseHeight = 15)

Plot the motifs in radialPhylog layout.

    browseMotifs(pfms = pfms, phylog = phylog, layout="radialPhylog", yaxis = FALSE, xaxis = FALSE, baseWidth=6, baseHeight = 15)

# docker container for motifStack

Docker container allows software to be packaged into containers which can be run in any platform using a virtual machine called boot2docker. To ease the installation of motifStack and its depencies, we have created a docker image containing all the components needed to run motifStack. Users can download the motifStack docker image using the following code snippet.

    cd ~ ## in windows, please try cd c:\\ Users\\ username
    docker pull jianhong/motifstack:latest
    mkdir tmp4motifstack ## this will be the share folder for your host and container.
    docker run -ti --rm -v ${PWD}/tmp4motifstack:/volume/data jianhong/motifstack:latest bash
      In motifstack:latest docker
        1  cd /volume/data
        2  git clone https://github.com/jianhong/motifStack.documentation.git
        3  cd motifStack.documentation/
        4  cp /usr/bin/matalign app/matalign-v4a
        5  cp /usr/bin/phylip/neighbor app/neighbor.app/Contents/MacOS/neighbor
        6  R cmd -e "rmarkdown::render('suppFigure2.Rmd')"
        7  R cmd -e "rmarkdown::render('suppFigure6.Rmd')"

You will see the test.pdf file in the folder of tmp4motifstack.

# plot motifs with ggplot2

motifs could be plotted by `geom_motif` function.

    pcm <- read.table(file.path(find.package("motifStack"),
                                "extdata", "bin_SOLEXA.pcm"))
    pcm <- pcm[,3:ncol(pcm)]
    rownames(pcm) <- c("A","C","G","T")
    markerRect <- new("marker", type="rect", start=6, stop=7, gp=gpar(lty=2, fill=NA, col="orange"))
    markerLine <- new("marker", type="line", start=3, stop=5, gp=gpar(lwd=2, col="red"))
    markerText <- new("marker", type="text", start=1, label="*", gp=gpar(cex=2, col="red"))
    motif <- new("pcm", mat=as.matrix(pcm), name="bin_SOLEXA",
                 markers=c(markerRect, markerLine, markerText))
    pfm <- pcm2pfm(motif)
    df <- data.frame(xmin=c(.25, .25), ymin=c(.25, .75), xmax=c(.75, .75), ymax=c(.5, 1),
                     fontfamily=c("Helvetica", "mono,Courier"), fontface=c(2, 1))
    df$motif <- list(pfm, pfm)

    library(ggplot2)

    ggplot(df, aes(xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax, motif=motif,
                   fontfamily=fontfamily, fontface=fontface)) +
        geom_motif() + theme_bw() + ylim(0, 1) + xlim(0, 1)

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    df <- data.frame(x=.5, y=c(.25, .75), width=.5, height=.25,
                     fontfamily=c("Helvetica", "mono,Courier"), fontface=c(2, 1))
    df$motif <- list(pfm, pfm)

    ggplot(df, aes(x=x, y=y, width=width, height=height, motif=motif,
                   fontfamily=fontfamily, fontface=fontface)) +
        geom_motif(use.xy=TRUE) + theme_bw() + ylim(0, 1) + xlim(0, 1)

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

    ## Warning in grid.Call.graphics(C_path, x$x, x$y, index, switch(x$rule, winding =
    ## 1L, : Path drawing not available for this device

# Session Info

    sessionInfo()

    ## R version 4.0.0 (2020-04-24)
    ## Platform: x86_64-apple-darwin17.0 (64-bit)
    ## Running under: macOS Mojave 10.14.6
    ##
    ## Matrix products: default
    ## BLAS:   /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
    ## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
    ##
    ## locale:
    ## [1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
    ##
    ## attached base packages:
    ##  [1] stats4    parallel  grid      stats     graphics  grDevices utils
    ##  [8] datasets  methods   base
    ##
    ## other attached packages:
    ##  [1] ggplot2_3.3.0        RColorBrewer_1.1-2   MotifDb_1.30.0
    ##  [4] motifStack_1.32.0    Biostrings_2.56.0    XVector_0.28.0
    ##  [7] ade4_1.7-15          MotIV_1.44.0         GenomicRanges_1.40.0
    ## [10] GenomeInfoDb_1.24.0  IRanges_2.22.0       S4Vectors_0.26.0
    ## [13] BiocGenerics_0.34.0  grImport2_0.2-0      knitr_1.28
    ##
    ## loaded via a namespace (and not attached):
    ##  [1] Rcpp_1.0.4.6                lattice_0.20-41
    ##  [3] png_0.1-7                   Rsamtools_2.4.0
    ##  [5] assertthat_0.2.1            digest_0.6.25
    ##  [7] R6_2.4.1                    evaluate_0.14
    ##  [9] highr_0.8                   pillar_1.4.3
    ## [11] zlibbioc_1.34.0             rlang_0.4.5
    ## [13] data.table_1.12.8           Matrix_1.2-18
    ## [15] rmarkdown_2.1               labeling_0.3
    ## [17] BiocParallel_1.22.0         stringr_1.4.0
    ## [19] htmlwidgets_1.5.1           RCurl_1.98-1.2
    ## [21] munsell_0.5.0               DelayedArray_0.14.0
    ## [23] compiler_4.0.0              rtracklayer_1.47.0
    ## [25] xfun_0.13                   pkgconfig_2.0.3
    ## [27] seqLogo_1.54.0              base64enc_0.1-3
    ## [29] htmltools_0.4.0             tidyselect_1.0.0
    ## [31] SummarizedExperiment_1.18.0 tibble_3.0.1
    ## [33] GenomeInfoDbData_1.2.3      matrixStats_0.56.0
    ## [35] XML_3.99-0.3                withr_2.2.0
    ## [37] crayon_1.3.4                dplyr_0.8.5
    ## [39] GenomicAlignments_1.24.0    MASS_7.3-51.6
    ## [41] bitops_1.0-6                jsonlite_1.6.1
    ## [43] gtable_0.3.0                lifecycle_0.2.0
    ## [45] magrittr_1.5                scales_1.1.0
    ## [47] stringi_1.4.6               splitstackshape_1.4.8
    ## [49] ellipsis_0.3.0              vctrs_0.2.4
    ## [51] BiocStyle_2.16.0            rGADEM_2.36.0
    ## [53] tools_4.0.0                 BSgenome_1.56.0
    ## [55] Biobase_2.48.0              glue_1.4.0
    ## [57] purrr_0.3.4                 jpeg_0.1-8.1
    ## [59] yaml_2.2.1                  colorspace_1.4-1
    ## [61] BiocManager_1.30.10

# Reference

1. Bembom, O. SeqLogo: Sequence logos for dna sequence alignments. R package version 1.5.4 (2006).

2. Foat, B. C., Morozov, A. V. & Bussemaker, H. J. Statistical mechanical modeling of genome-wide transcription factor occupancy data by matrixreduce. Bioinformatics 22, e141–e149 (2006).

3. Mercier, E. & Gottardo, R. MotIV: Motif identification and validation. R package version 1.10.0 (2010).

4. S, M. & PV, B. STAMP: A web tool for exploring dna-binding motif similarities. Nucleic Acids Res. 35(Web Server issue), W253–W258 (2007).