
  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  lib.r                                                                                  #
  #           Last Updated Funclist  :  08 Feb 2015,  5:12 AM (Sunday)                                                         #
  #                                                                                                                            #
  #           Author Name            :  Rick Saporta                                                                           #
  #           Author Email           :  RickSaporta@gmail.com                                                                  #
  #           Author URL             :  www.github.com/rsaporta                                                                #
  #                                                                                                                            #
  #           Packages Called        :                                                                                         #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   lib                ( pkg, newest=FALSE, rforge=newest, update=rforge, dependencies=TRUE, installSuggestions=TRUE         #
  #                        , quietly=FALSE, source=FALSE )                                                                     #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #

lib <- function(pkg, newest=FALSE, rforge=newest, update=rforge, dependencies=TRUE, installSuggestions=TRUE, quietly=FALSE, source=FALSE) { 
# newest is a shorthand for `update` and `rgorge`
# Note that if `rforge` is selected, this automatically sets update to TRUE
#
# if nothing to load, it will return TRUE

## Now done in the default arguments.  Keeping this here in case needing to revert. 
# old  # newest is a shortcut for  rforge & update both TRUE
# old  if (newest)
# old    rforge <- update <- TRUE
# old
# old  # if `rforge` flagged on, that probably means update, unless explicit otherwise
# old  if (rforge && missing(update))
# old    update <- TRUE 

  # The idea is that if package is not quoted, it should still work. 
  # -------------------------------------------------------------- #
  pkg.char <- as.character(substitute(pkg))
  if(inherits(substitute(pkg), "call"))
    pkg.char <- pkg.char[-1]

  ## Determine if we should substitute pkg.char for pkg. 
  # note that pkg.char is what was sent to this function.
  #      it might be the name of an object, thus we check if it exists
  #      if it does exist, then we do not substitute.
  if (!exists(pkg.char) || !is.character(substitute(pkg)) ) {
    # Next we check if pkg is a character. If it isn't, then we do substitute.
    #  The isErr part is to shortcircuit the check for is.character of an object that does not exist
    if (isErr(is.character(pkg)) || !is.character(pkg)) 
      pkg <- pkg.char
  } 
  # -------------------------------------------------------------- #

  ## Error Check
  if (!(isTRUE(length(pkg)>0))) {
    warning("`pkg` has length 0. Nothing to load.")
    return(TRUE)
  }

  if (length(pkg)==1 && pkg=="data.table" && rforge && missing(source))
    source <- TRUE
  if (length(pkg)==1 && pkg=="data.table" && source) {
    devtools::install_github("Rdatatable/data.table", build_vignettes = FALSE)
    return(invisible(TRUE))
  }

  pkg[tolower(pkg) == "ggplot"] <- "ggplot2"
  pkg[tolower(pkg) == "rcurl"]  <- "RCurl"

  ## ggplot loads in some extra packages. Also, remind myself about ggvis
  if ("ggplot2" %in% tolower(pkg)) {
    if (!any(grepl("ggplot2", search())))
      message("Remember to check out   ggvis")
    pkg <- c(pkg, "scales", "gridExtra", "grid")
  }

  pkg <- unique(pkg)

  browser(expr=inDebugMode("lib"), text="in lib() right before if(!update)")

  func.quiet <- if (quietly) suppressPackageStartupMessages else identity

  check <- c()
  # if update is flagged, skip this step and first install
  if (!update) {

    for (p in pkg)
        suppressWarnings(check[p] <- func.quiet(do.call(require, list(package=p, quietly=quietly))))

    ## if all packages loaded, we're done
    if (all(check))
      return(invisible(check))

    # else, filter the list down to just the errors
    pkg <- pkg[!check]

    # if failed, search for matches in lib and try again
    allPkgs <- dir(.libPaths())
    hits <- match(tolower(eval(pkg)), tolower(dir(.libPaths())))
    if(!all(is.na(hits))) {

      pkg[!is.na(hits)] <- allPkgs[hits][!is.na(hits)]

      # try again
      for (p in pkg)
        suppressWarnings(check[p] <- do.call(require, list(package=p, quietly=quietly)))

      if (all(check))
        return(invisible(check))
    }
  }

  # else
  if (missing(source) && identical(pkg, "data.table")) 
    soruce <- TRUE
  type  <- ifelse(source, "source", getOption("pkgType"))
  repos <- ifelse(rforge, "http://R-Forge.R-project.org", getOption("repos"))
  install.packages(pkg, dependencies=dependencies, repos=repos, type=type)

  ## Catch any misnamed items
  if (exists("last.warning")) {
    w <- names(last.warning)
    w <- grep("Perhaps you meant", w, value=TRUE)
  } else 
    w <- character()

  # if flagged, and there are suggestions from the server, try those
  if(installSuggestions && length(w) > 0) {
    ## Extract just the suggested package name
    re <- regexpr("‘.+’", w)
    en <- re + attr(re, "match.length") - 1
    w  <- substr(w, re+1, en-1)
    cat("Trying packages\n\t",paste(w, collapse="\n\t"), "\n")
    install.packages(w, dependencies=dependencies, repos=repos, type=type)
    # Load, note that we are also banking the new name
    for (p in w)
          suppressWarnings(check[p] <- do.call(require, list(package=p, quietly=quietly)))
  }

  ## TODO:  if failed due to dependencies, (re)install dependencies
  ##     eg:  "Error : package ‘XML’ was built before"

  for (p in pkg)
    suppressWarnings(check[p] <- do.call(require, list(package=p, quietly=quietly)))

  return(invisible(check))
}
