##  SIMILAR TO JESUS, BUT USES   write.table()  FOR MATRIX-LIKE OBJECTS THAT DO NOT HAVE LIST-LIKE COLUMNS
##   Once confirmed that this works properly, replace `jesus()`


jesus2 <- function(..., dir=ifelse(exists("outDir"), outDir, as.path(getwd(), "out")), subDir=sub, 
                                pos=1, sub=TRUE, stampDir=TRUE, stampFile=FALSE, summary=TRUE, envir="",
                                tablesAsCSV=TRUE,   row.names=FALSE, col.names=FALSE)  {
    ##  Like saveit() but can take multiple objects as arguments
    ##
    ##     saves objects passed as (...) arguments to file of type .Rda and with 
    ##     name of file same as name of obj + time stamp
    ##     in location: dir
    ##     tablesAsCSV:  if TRUE,  matrix-like (2-dim objects) will be written to csv
    ##     subDir:  if TRUE, will create subdir data_bak 
    ##                    inside dir and use that folder. (if alreaddy exists, will just use)
    #S     sub:  a synonym for subDir. (since use of ... does not allow for partial matches) 
    ##
    ## returns:  the path/to/file.Rda where objects were saved

    ## NOTE TO SELF:  You cannot use  `dots.list` and `list(...)` interchangeably in substitute
    ##                    dots.list <- list(...)
    

    # get objects from dots
    objNames <- as.list(as.character(substitute(list(...)))[-1L])

    # check for arguments being (eval(...))
    whichAreEval <- sapply(objNames, function(x) grepl("^eval\\(.+\\)$", x))

    if (any(whichAreEval))  {
      # confirm they are calls
      whichAreCalls <- sapply(substitute(list(...))[-1], is.call)
      # proceed only if they match
      if (identical(whichAreCalls, whichAreEval)) {
        objNames2 <-  list(...)[whichAreCalls]
        objNames <- unlist(c(objNames2, objNames[!whichAreCalls]))
      }
    }

### TODO:  June 2013.  Apparently the `eval(vector.of.obj.names)` was not working. I wrote the part immediately above this. 
###        Confirm all is working correctly.  
# -- check this -- #    # TODO:  double-check pos value.  It might be off. 
# -- check this -- #    # check any value is eval(XX), if so parse it. Collect all values into a single vector.   
# -- check this -- #    objNames <- unlist( lapply(objNames, function(ob) 
# -- check this -- #      if(substr(ob, 1, 5)=="eval(")   eval(parse(text=substr(ob, 6, nchar(ob)-1)), envir=ifelse(is.environment(envir), envir, parent.frame(pos+1)) )  else  ob
# -- check this -- #    ) )


    # No need to save any object twice
    objNames <- unique(objNames)

    #----- ERROR CHECKS ------#
    # If any of the assignment operators are found in the list, throw an error
    if(detectAssignment(objNames)) 
      stop("Cannot assign in the call to this function.")
    #----- ERROR CHECKS ------#

    # Check that the objects to be saved exist
    NotPresent <- !(sapply(objNames, exists))
    if (any(NotPresent)) {
      warning("The following objects were not found and hence could not be saved:\n    ", paste(objNames[NotPresent], collapse="    "), "\n")
      objNames <- objNames[!NotPresent]
    }

    # if flag is true, add appropriate subdir
    if (subDir) 
      dir <- as.path(dir, "data_bak")

    # add timeStamp to dir if required
    if(stampDir)
      dir <- paste0(as.path(dir), "_", timeStamp())

    # Create dir if needed
    dir.create(as.path(dir), recursive=TRUE, showWarnings=FALSE)


    if (tablesAsCSV) {

      ## Determine which are matrix-like
      twoDimmed <- gapply(objNames, is.twodim, pos=pos+1, simplify=TRUE)
      # determine which have list columns 
      hasLists  <- gapply(objNames, has.listColumn, pos=pos+1, simplify=TRUE)
      # keep only two dimmed that do not have list columns
      twoDimmed <- (twoDimmed)  & !(hasLists)

      # Track any failures  ## CURENTLY NOT IMPLEMENTED
      failed <- as.character(c())

      # isolate just those that will be CSV'd
      csv.objNames <- objNames[twoDimmed]

      # create the file paths, cleaning objNames of bad chars
      csv.fileWithPath <- sapply(objNames, mkSaveFileNameWithPath, ext=".csv", dir=dir, addTimeStamp=stampFile)

      for (i in seq_along(csv.objNames)) {
        obj <- get(csv.objNames[[i]], envir=pos+1)  # double check pos
        fil <- csv.fileWithPath[[i]]

        ## TODO: add try() and save any failures to `failed`
        write.table(obj, file=fil, append=FALSE, quote=TRUE, sep="|", 
                    row.names=row.names, col.names=col.names, qmethod="escape", fileEncoding="UTF-8")
      }

      # clear out those saved as CSV
      objNames <- objNames[!twoDimmed]
      objNames <- c(objNames, failed)
    }

    # create the file paths, cleaning objNames of bad chars
    rda.fileWithPath <- sapply(objNames, mkSaveFileNameWithPath, ext=".rda", dir=dir, addTimeStamp=stampFile)

    # Save the object
    tryCatch(mapply(function(obj, thefile)
              # note that with the save+do.call we are going in an extra two environments, hence pos + 2  (also, tested with pos+1, pos+3, both wrong)
              do.call(save, args=list(obj, envir=parent.frame(pos+2), file=thefile) )  # pos + 3 will be off if 
          , objNames, rda.fileWithPath), 
        error = saveErrorHandle)

            ## This does NOT work. 
            # filesCreated <- do.call(saveit, args=list(objNames, pos=pos+1, dir=dir, addTimeStamp=stampFile))
            # return(filesCreated )
    

    ret.fileWithPath <- c(csv.fileWithPath, rda.fileWithPath)
    # return the path/to/files or just a summary
    if (summary)
      return(list('quantity'=paste(length(ret.fileWithPath), "files were created in:"), 'dir'=dir))
    return('back.up.files'=ret.fileWithPath)
  }







