.packageName <- "ChromoViz"
"cViz" <-
function (feature, bandPosFile, refSp="human") 
{
    # SUBSET
    featureSet <- subset(feature, !is.na(begin))
    for(i in 1:8) {
       featureSet[[i]] <- as.vector(featureSet[[i]])
    }    
    featureSet <- subset(featureSet, value!=0)
    sel <- featureSet$chrom %in% bandPosFile$chrom
    featureSet <- featureSet[sel, ]
        
    chromList <- cViz.distinctNames(featureSet$chrom)
    #chromList <- cViz.distinctNames(bandPosFile$chrom)   
    

    lenOfChromList <- length(chromList)
    for (i in 1:lenOfChromList) {
        theChrom <- chromList[i]
        frameDesign <- list()
        frameDesign$height <- 2.5
        frameDesign$top <- 1.5
        frameDesign$bottom <- 1
        frameDesign$cex <- 0.7
        frameDesign$interval <- 0.5
        frameDesign$imgFileWidth <- 800/80
        frameDesign$imgFileHeight <- 150/80
        frameDesign$mai <- c(0.1, 0.1, 0.1, 0.1)
        eachChr <- subset(bandPosFile, chrom == theChrom)
        cViz.drawChr(eachChr, theChrom, frameDesign, refSp)
        frameDesign$height <- 2.5
        frameDesign$top <- 2
        frameDesign$bottom <- 1
        frameDesign$imgFileHeight <- 50/80
        trackList <- cViz.drawFeature(featureSet, eachChr, theChrom, 
            frameDesign)                           
        cViz.makeChromWrapperHtml(theChrom, trackList)
        
    }        
    
    for (i in 1:lenOfChromList) {
        theChrom <- chromList[i]
        chrSVGFile <- paste(theChrom, "svg", sep = ".")
        pat <- paste("^", theChrom, "[.].+.(.svg$)", sep = "")
        otherSVGFileList <- list.files(path = ".", pattern = pat)
        outFile <- paste("merged", chrSVGFile, sep = ".")
        cViz.mergeSVG(chrSVGFile, otherSVGFileList, outFile)
        otherSVGFileList <- append(otherSVGFileList, chrSVGFile)
    }
    cViz.makeHeaderHtml("header")
    cViz.makeFrameHtml("index", chromList[1])
    data(svgControl)
    write(svgControl, file = "control.js")
}

"cViz.addAnnoNodes2SVG" <-
function(svgFile, curGid, theItems) {
    inFile <- xmlTreeParse(svgFile)
    curNode <- inFile$doc$children$svg
    
    ### CREATE ancestor NODE 
    ancestorAttrs <- xmlAttrs(curNode)
    ### INSERT NAMESPACE INFORMATION
    ancestorAttrs <- append(ancestorAttrs, "http://www.w3.org/1999/xlink")
    names(ancestorAttrs)[length(ancestorAttrs)] <- "xmlns\:xlink"
    ancestorNode <- xmlNode("svg", attrs=ancestorAttrs)
      
    ### CREATE g NODE
    rootNode <-  xmlNode("g", attrs=c(id=curGid))
    
    ### COPY CHILDREN to THE root NODE
    childList <- xmlChildren(curNode)
    childListName <- names(childList)
    childNodeNum <- xmlSize(childList)   
    for(j in 3:childNodeNum) {
        if(childListName[j] == "rect") {
           childList[[j]] <- cViz.insertNewAttrValue(childList[[j]],
                            "id",  theItems[j-2]) 
        }            
        rootNode <- append.XMLNode(rootNode, childList[[j]])
    }
    ancestorNode <- append.XMLNode(ancestorNode, rootNode )
    
    ### APPEND use NODE to THE root NODE
    useAttrs <- c(id=paste(curGid, "1", sep="\_"), info=0,
                  "xlink\:href"=paste("\#",curGid, sep=""),
                  transform="translate(0,0)", x="0", y="0",
                  style="stroke-opacity:.4", visibility="hidden")
    useNode <- xmlNode("use", attrs=useAttrs)    
    ancestorNode <- append.XMLNode(ancestorNode, useNode)
            
    ### WRITE INTO A FILE     
    fileHeader <- "\<?xml version=\"1.0\" standalone=\"yes\"?\>"
    fileContents <- paste(fileHeader, toString(ancestorNode), sep="")       
    cat(fileContents, file=svgFile, append=F)                      
    #cat(toString(ancestorNode), file=svgFile, append=F)
}

"cViz.addZeroToTheSingleDigit" <-
function(vec)
{
   idx <- grep("^chr[1-9]$|^chr[1-9]_" ,  vec, perl = TRUE) 
   vec[idx] <- sub("chr", "chr0", vec[idx])
   vec
}

"cViz.distinctNames" <-
function(v1) {
      names( table(v1))
}

"cViz.drawChr" <-
function (eachChr, chrom, frameDesign, refSp) 
{
    len <- length(eachChr$begin)
    top <- frameDesign$top
    bottom <- frameDesign$bottom
    cex <- frameDesign$cex
    interval <- frameDesign$interval
    eachChr$shadeCol <- rep("", len)
    
    if(refSp == "human") { 
        for (i in 1:len) {
            if (eachChr$stain[i] == "acen") 
                eachChr$shadeCol[i] <- "skyblue2"
            else if (eachChr$stain[i] == "gneg") 
                eachChr$shadeCol[i] <- "gray92"
            else if (eachChr$stain[i] == "gpos25") 
                eachChr$shadeCol[i] <- "gray75"
            else if (eachChr$stain[i] == "gpos50") 
                eachChr$shadeCol[i] <- "gray60"
            else if (eachChr$stain[i] == "gpos75") 
                eachChr$shadeCol[i] <- "gray45"
            else if (eachChr$stain[i] == "gpos100") 
                eachChr$shadeCol[i] <- "gray30"
            else if (eachChr$stain[i] == "gvar") 
                eachChr$shadeCol[i] <- "khaki2"
            else eachChr$shadeCol[i] <- "brown"
        }
    }   
    
    if(refSp == "mouse") { 
        for (i in 1:len) {
            if (eachChr$stain[i] == "gneg") 
                eachChr$shadeCol[i] <- "gray92"
            else if (eachChr$stain[i] == "gpos100") 
                eachChr$shadeCol[i] <- "gray30"                 
            else if (eachChr$stain[i] == "gpos33") 
                eachChr$shadeCol[i] <- "gray75"
            else if (eachChr$stain[i] == "gpos66") 
                eachChr$shadeCol[i] <- "gray60"
            else if (eachChr$stain[i] == "gpos75") 
                eachChr$shadeCol[i] <- "gray45"                    
            else eachChr$shadeCol[i] <- "brown"
        }
    } 
        
    devSVG(file = paste(chrom, "svg", sep = "."), 
        width = frameDesign$imgFileWidth, 
        height = frameDesign$imgFileHeight)
    par(mai = frameDesign$mai)
    plot(c(0, 0), c(0, frameDesign$height), type = "n", xlim = c(0, 
        max(eachChr$end) * 1.1), axes = F, xlab = "", ylab = "")
    for (i in 1:len) {
        if (eachChr$stain[i] != "acen") {
            if (i%%2 == 1) {
                rect(eachChr$begin[i], bottom, eachChr$end[i], 
                  top, border = eachChr$shadeCol[i], col = eachChr$shadeCol[i])
                text((3 * eachChr$begin[i] + eachChr$end[i])/4, 
                  bottom - interval, pos = 1, labels = eachChr$band[i], 
                  srt = 90, cex = cex)
            }
            else {
                rect(eachChr$begin[i], bottom, eachChr$end[i], 
                  top, border = eachChr$shadeCol[i], col = eachChr$shadeCol[i])
                text((3 * eachChr$begin[i] + eachChr$end[i])/4, 
                  top + interval, pos = 3, labels = eachChr$band[i], 
                  srt = 90, cex = cex)
            }
        }
    }
    
    if(refSp == "human") { 
        i <- 1
        while (eachChr$stain[i] != "acen") {
            i <- i + 1
        }
        leftCenX <- c(eachChr$begin[i], eachChr$end[i], eachChr$begin[i])
        leftCenY <- c(bottom, (bottom + top)/2, top)
        polygon(leftCenX, leftCenY, border = eachChr$shadeCol[i], 
            col = eachChr$shadeCol[i])
        i <- i + 1
        rightCenX <- c(eachChr$begin[i], eachChr$end[i], eachChr$end[i])
        rightCenY <- c((bottom + top)/2, bottom, top)
        polygon(rightCenX, rightCenY, border = eachChr$shadeCol[i], 
            col = eachChr$shadeCol[i])
        mtext(text = chrom, side = 4, at = c(max(eachChr$end) * 1.05, 
            (top + bottom)/2), las = 2, adj = 1, cex = cex)
    }
                
    dev.off()
}

"cViz.drawFeature" <-
function (inFile, eachChr, theChrom, frameDesign)
{
  ### SET FRAME DESIGN PARAMETERS
  top <-  frameDesign$top
  bottom <- frameDesign$bottom
  cex <- frameDesign$cex

  ### SELECT FEATURE
  distinctNames <- sort( cViz.distinctNames(inFile$track)  )  
  lenOfDistinctNames <- length(distinctNames)

  ### CHOOSE NAMES ONLY WITH VALUES FROM THE distinctNames
  chosenDistinctNames <- vector()

  itemList <- list()
  for(j in 1:lenOfDistinctNames) {
      subChunk <- subset(inFile, 
               (track == distinctNames[j] ) & (chrom == theChrom) & (value != 0.0)) 
    
      if(length(subChunk$track) > 0) {
          chosenDistinctNames <- append(chosenDistinctNames, distinctNames[j])
         
          ### item 
          ###   example) accession number
          itemList[[j]] <- as.vector(subChunk$item)
          
          pngFileName <- paste(theChrom, distinctNames[j],  sep=".")

          ### PREPARE FRAME
          svgFile <- paste(pngFileName, "svg", sep=".")
          devSVG(file=svgFile,   width = frameDesign$imgFileWidth,  
                 height=frameDesign$imgFileHeight)

#   png(file=paste(pngFileName, "png", sep="."), 
#         width=frameDesign$imgFileWidth, height=frameDesign$imgFileHeight)
          par(mai=frameDesign$mai)
          plot(c(0, 0), c(0, frameDesign$top), type="n",  xlim=c(0, max(eachChr$end)*1.1),  
               axes=F,  xlab="", ylab="" ) 

          ### VALUE
          len <- length(subChunk$begin)
          scale <- (top-bottom)/max(abs(subChunk$value))
          for(k in 1:len) {
             rect( subChunk$begin[k], bottom,
                   subChunk$end[k],  bottom+subChunk$value[k]*scale,
                   border="orangered", col="orangered")
#       rect( subChunk$begin[k], bottom,
#          subChunk$begin[k],  bottom+subChunk$value[k]*scale,
#               border="orangered", col="orangered")
          }  
          lines( c(min(eachChr$begin),  max(eachChr$end)), c(bottom, bottom), col="gray") 
          mtext(text=subChunk$track[len], side=4, at=c(max(eachChr$end)*1.05, bottom), 
                las=2, adj=1, font=1, cex=cex)
          dev.off()
    
          ### APPEND ANNOTATION NODES TO THE SVG NODE
          curGid <- distinctNames[j]
          cViz.addAnnoNodes2SVG(svgFile, curGid, itemList[[j]])                 
      }
  } # THE END OF for LOOP 
  
  chosenDistinctNames
}

"cViz.getHeightOfPolylinePoints" <-
function(inFile)
{
svgTags <- xmlTreeParse(inFile)
targetNode <-  svgTags$doc$children$svg$children$g    
pointValues <- xmlAttrs(targetNode$children$polyline)[["points"]]
strsplit(pointValues, " ")[[1]][3]
}

"cViz.incPolylineAttrValue" <-
function(theNode, delta)
{ 
  theAttrName <- "points"
  attrNames <- names(xmlAttrs(theNode))
  attrValues <- as.vector(xmlAttrs(theNode))
  attrNumber <- length(attrNames)
  newAttrValues <- attrValues
  names(newAttrValues) <- attrNames

  for(i in 1:attrNumber){ 
  
    if(attrNames[i] == theAttrName) {
     
      strPoints <- strsplit(newAttrValues[i] , " ")[[1]]
      strPoints[3] <- as.numeric(strPoints[3]) + delta
      strPoints[6] <- as.numeric(strPoints[6]) + delta      
      newAttrValues[i] <- paste(strPoints[1], ",", strPoints[3], 
                         strPoints[4],  ",", strPoints[6], sep=" ")  
    }
  }
 
  attrVector <- attrValues
  names(attrVector) <- attrNames
  newNode <- xmlNode(xmlName(theNode), attrs=newAttrValues)
  newNode
}

"cViz.incSVGviewBoxValue" <-
function(theNode, delta)
{ 
  theAttrName <- "viewBox"
  attrNames <- names(xmlAttrs(theNode))
  attrValues <- as.vector(xmlAttrs(theNode))
  attrNumber <- length(attrNames)
  newAttrValues <- attrValues
  names(newAttrValues) <- attrNames

  for(i in 1:attrNumber){ 
  
    if(attrNames[i] == theAttrName) {
     
      strPoints <- strsplit(newAttrValues[i] , ",")[[1]]
      strPoints[4] <- as.numeric(strPoints[4]) + delta
      newAttrValues[i] <- paste(strPoints[1], strPoints[2], 
                                strPoints[3], strPoints[4], sep=",")  
    }
  }
 
  attrVector <- attrValues
  names(attrVector) <- attrNames
  newNode <- xmlNode(xmlName(theNode), attrs=newAttrValues)
  newNode
}

"cViz.incSingleAttrValue" <-
function(theNode, theAttrName, delta)
{
  attrNames <- names(xmlAttrs(theNode))
  attrValues <- as.vector(xmlAttrs(theNode))
  attrNumber <- length(attrNames)
  newAttrValues <- attrValues
  names(newAttrValues) <- attrNames

  for(i in 1:attrNumber){ 
    if(attrNames[i] == theAttrName) {
      newAttrValues[i] <- as.numeric(xmlAttrs(theNode)[[theAttrName]] )  + 
                          as.numeric(delta)
    }
  }
  
  attrVector <- attrValues
  names(attrVector) <- attrNames
  newNode <- xmlNode(xmlName(theNode), attrs=newAttrValues)
  newNode
}

"cViz.incTextAttrValue" <-
function(theNode, delta)
{ 
  theAttrName <- "transform"
  theXmlValue <- xmlValue(theNode)
  attrNames <- names(xmlAttrs(theNode))
  attrValues <- as.vector(xmlAttrs(theNode))
  attrNumber <- length(attrNames)
  newAttrValues <- attrValues
  names(newAttrValues) <- attrNames

  for(i in 1:attrNumber){ 
  
    if(attrNames[i] == theAttrName) {
                                  
      theTransform <- gsub("[a-z(,)]", " ", newAttrValues[i], perl=TRUE)
      theTransform <- strsplit(theTransform, " +")[[1]]
      theTransform[3] <- as.numeric(theTransform[3]) + delta
      newAttrValues[i] <- paste("translate(", theTransform[2], ",",
                             theTransform[3], ")  ", sep="")    
    }
  }
 
  attrVector <- attrValues
  names(attrVector) <- attrNames
  newNode <- xmlNode(xmlName(theNode), value=theXmlValue, attrs=newAttrValues)
  newNode
}

"cViz.insertNewAttrValue" <-
function(theNode, theAttrName, theAttrValue)
{
  newAttrValues <- as.vector(xmlAttrs(theNode))
  names(newAttrValues) <- names(xmlAttrs(theNode))

  newAttrValues <- append(newAttrValues, theAttrValue, after=0)
  names(newAttrValues)[1] <- theAttrName
  newNode <- xmlNode(xmlName(theNode), attrs=newAttrValues)
 
  newNode  
}

"cViz.loadFiles" <-
function(fileList)
{
   lenOfFileList <- length(fileList)
   if(lenOfFileList > 0) {
      result <- read.table(fileList[1], sep="\t", na.strings = "NA",  header=T, as.is=TRUE)
      result$chrom <- cViz.addZeroToTheSingleDigit(result$chrom)
 
      if(lenOfFileList > 1) {
         for(i in 2:lenOfFileList) {
            tempDataFrame <- read.table(fileList[i], sep="\t", 
                             na.strings = "NA",  header=T, as.is=TRUE)
            tempDataFrame$chrom <- cViz.addZeroToTheSingleDigit(tempDataFrame$chrom)
            result <- rbind(result, tempDataFrame)  
         }
      }
   }

   result <- subset(result, track != "NA")
}

"cViz.makeChromWrapperHtml" <-
function(theChrom, trackList)
{
   includeFile <- paste("merged", theChrom, "svg", sep=".")   
   ### OPEN AN HTML FILE 
   htmlOut <- file( paste(theChrom, ".html", sep=""), "w")

   ### INCLUDE CHROMOSOME
   cat("<HTML><HEAD>",file = htmlOut, sep="\n")
   cat("<script language=\"javascript1.2\" src=\"control.js\" type=\"text/javascript\">", 
          file=htmlOut, sep="\n") 
   cat("</script></HEAD><BODY>", file=htmlOut, sep="\n")     
   cat("<TABLE align=center><BR><TR><TD width=800 valign=\"top\">", 
             file=htmlOut, sep="\n")             
   cat("<embed name=\"Chromosome\"", file=htmlOut)
   cat(" width=\"800\" height=\"600\" src=\"", file=htmlOut)
   cat(includeFile, file = htmlOut)
   cat("\"></TD>", file = htmlOut, sep="\n")     
   cat("<TD width=\"200\" valign=\"top\"><FORM name=\"FindData\"><FONT size=\"2\">", 
             file = htmlOut, sep="\n")         
   cat("<input type=\"text\" name=\"accNum\" size=\"15\">", file = htmlOut, sep="\n")
   cat("<input type=\"button\" value=\"Search\" onClick=\"FindAccNum(\'Chromosome\')\;\"><br><br><br>",
         file = htmlOut, sep="\n")
      
   lenOfTrackList <- length(trackList)
   for(i in 1:lenOfTrackList ) {
        cat("<input type=\"checkbox\" name=\"", file = htmlOut)
        cat(paste(trackList[i], "1", sep="\_"), file = htmlOut)
        cat("\" unchecked onClick=\"MovetoZero(\'Chromosome\', this)\;\">",file = htmlOut, sep="\n")
        cat(trackList[i], file = htmlOut)
        cat("<br>", file = htmlOut, sep="\n")
   }
   cat("</FONT></FORM></TD></TR></TABLE>", file = htmlOut, sep="\n")
   cat("<BR></BODY></HTML>", file = htmlOut, sep="\n")

   ### CLOSE THE HTML FILE
   close(htmlOut)
}

"cViz.makeFrameHtml" <-
function (reportName, initMainPrefix) 
{
    htmlOut <- file(paste(reportName, "html", sep = "."), "w")
    cat("<HEAD><HEAD><TITLE>ChromoViz Output</TITLE></HEAD>", 
        file = htmlOut, sep = "\n")
    cat("<FRAMESET rows=\"10%, 90%\" framespacing=0 border=0 frameborder=0>", 
        file = htmlOut, sep = "\n")
    cat("<FRAME NAME=\"header\"  scrolling=no  noresize target=\"main\" ", 
        file = htmlOut)
    cat("src=\"header.html\" >", file = htmlOut, sep = "\n")
    cat("<FRAME NAME=\"main\"  scrolling=auto  noresize target=\"main\"  src=\"", 
        file = htmlOut)
    cat(paste(initMainPrefix, "html", sep = "."), file = htmlOut)
    cat("\" ><NOFRAMES><BODY LINK=yellow VLINK=red ALINK=yellow></BODY>", 
        file = htmlOut, sep = "\n")
    cat("</NOFRAMES><FRAMESET></HTML>", file = htmlOut)
    close(htmlOut)
}

"cViz.makeHeaderHtml" <-
function (fileName) 
{
    pat <- paste("chr", ".*.(.html$)", sep = "")
    reportList <- list.files(path = ".", pattern = pat)

    # SORT 
    chrNum <- reportList
    len <- length(chrNum)
    for(i in 1:len) {
       chrNum[i] <- strsplit(reportList[i], "\\.")[[1]][1]
       chrNum[i] <- substr(chrNum[i], 4, 7) 
    }
    sel <- chrNum %in% c(1:9)
    for(i in 1:len) {
      if(sel[i]) {
        chrNum[i] <- paste( "0", chrNum[i], sep="")  
      }
    }
    ord <- order(chrNum)
    reportList <- reportList[ord]


    lenOfReportList <- length(reportList)
    htmlOut <- file(paste(fileName, "html", sep = "."), "w")
    cat("<HTML><HEAD><TITLE>ChromoViz</TITLE><BODY>", file = htmlOut, 
        sep = "\n")
    cat("<TABLE ALIGN=CENTER CELLPADDING=0 CELLSPACING=0><TR>", 
        file = htmlOut, sep = "\n")
    for (i in 1:lenOfReportList) {
        cat("<td width=20><p align=center><a target=main a href=\"", 
            file = htmlOut)
        cat(reportList[i], file = htmlOut)
        cat(paste("\">", substr(reportList[i], 4, nchar(reportList[i]) - 
            5), sep = ""), file = htmlOut)
        cat("</a></p></td>", file = htmlOut, sep = "\n")
    }
    cat("</TR></TABLE></BODY></HTML>", file = htmlOut, sep = "\n")
    close(htmlOut)
}

"cViz.mergeSVG" <-
function(chromFile, trackFilesList, outFile)
{
    ### MAKE A CHROMOSOME NODE
    chromNode <- xmlTreeParse(chromFile)
    chromNodeSize <- xmlSize(xmlRoot(chromNode))

    ### GET height AND SAVE AS A delta
    curNode <- chromNode$doc$children$svg
    chrHeight <- as.numeric( xmlAttrs( curNode )[["height"]])
    trackFilesListNumber <- length(trackFilesList)
    tempChildNode <- xmlTreeParse(trackFilesList[1])$doc$children$svg
    delta <- as.numeric( xmlAttrs(tempChildNode)[["height"]])

    ### MAKE A ROOT NODE AND RESET height
    rootAttrs <- xmlAttrs( curNode )
    ### APPEND NAME SPACE
    rootAttrs <- append(rootAttrs, "http://www.w3.org/1999/xlink")
    names(rootAttrs)[length(rootAttrs)] <- "xmlns\:xlink"
    rootNode <- xmlNode("svg", attrs=rootAttrs ) 
    rootNode <- cViz.incSingleAttrValue(rootNode, 
                 "height", delta*trackFilesListNumber)          
    rootNode <- cViz.incSVGviewBoxValue(rootNode, 
                  delta*trackFilesListNumber)                   

    ### APPEND CHROMOSOMAL BAND NODES
    for(i in 1:chromNodeSize) {                    
       rootNode <- append.XMLNode(rootNode,  curNode[[i]])
    } 

    ### ATTACH OTHER TRACK FILES
    for(i in 1:trackFilesListNumber) { 
       moveDown <- chrHeight + i*delta       
       
       trackNode <- xmlTreeParse(trackFilesList[i], addAttributeNamespaces=T)
       useNode <- xmlRoot(trackNode)$children$use
       
       groupChildren <- xmlRoot(trackNode)$children$g
  
       ### CREATE NEW GROUP NODE
       newGroupNode <- xmlNode("g", attrs=xmlAttrs(groupChildren) )

       ### UPDATE GROUP CHILDREN height
       childList <- xmlChildren(groupChildren)
       childNames <- names(childList)
       tagNum <- xmlSize(groupChildren)
       newInfo <- 0
       
       for(j in 1:tagNum) {
           if(childNames[j] == "rect") {
                childList[[j]] <- cViz.incSingleAttrValue(childList[[j]], "y", moveDown) 
           }
           if(childNames[j] == "polyline") {
                childList[[j]] <- cViz.incPolylineAttrValue(childList[[j]], moveDown)
                newInfo <- strsplit(xmlAttrs(childList[[j]])[["points"]], " ")[[1]][3]                
           }    
           if(childNames[j] == "text") {
               childList[[j]] <- cViz.incTextAttrValue(childList[[j]], moveDown) 
           }               
           
           if((i==1) && (j==1)) {
               newInfo <- xmlAttrs(childList[[j]])[["y"]]
           }         
                    
           newGroupNode <- append.XMLNode(newGroupNode, childList[[j]])        
       }
    
       ### APPEND NEW GROUP NODE TO THE ROOT NODE
       rootNode <- append.XMLNode(rootNode, newGroupNode)
       
       ### APPEND use NODE TO THE ROOT NODE
       useNode <- xmlRoot(trackNode)$children$use
       useNode <- cViz.incSingleAttrValue(useNode, "info", newInfo)
       rootNode <- append.XMLNode(rootNode, useNode)
   }

   ### WRITE INTO A FILE
   file.create(outFile)
   write("<?xml version=\"1.0\"?>", file=outFile, append=F)   
   cat(toString(rootNode), file=outFile, append=T)                 
}

