
  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  simpleFromJSON.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        :  NA                                                                                     #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   simpleFromJSON     ( x, expectedCols=NULL )                                                                              #
  #   simpleParse        ( s, splitOn=funkyString )                                                                            #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #

simpleFromJSON <- function(x, expectedCols=NULL) {
  ## First try normal parsing
  ret <- try(fromJSON(x), silent=TRUE)
  # If succesful, return that
  if(!isErr(ret))
    return (ret)
  ## Otherwise, manually parse

  ## Confirm we have a character or factor
  if(is.factor(x))
    x <- as.character(x)
  if(!is.character(x))
    stop("x should be a character or factor")
  ## Remove start / stop braces
  x <- gsub("\\b\\{|\\}\\b", "", x)

  if (!is.null(expectedCols)) {
    ## Add a trailing comma.  This is useful if the field is blank, strsplit will not otherwise pick it up 
    x <- paste0(x, ",")

    # split on  : (plus white space)
    splat <- strsplit(x, regOr(paste0(expectedCols, "\\s*:\\s*")))

    # then drop trailing commas and also drop the first column, which is blank. 
    ret <- t(sapply(splat, function(ss)  gsub(",\\s*$", "", ss[-1])  ))

    ## Error-check. No stragglers, every row has correct number of fields
    if(ncol(ret) != length(expectedCols))
      stop("\nIncorrect number of fields from the JSON splice.\nExpected fields are:\n\t", 
            paste(expectedCols, collapse="\t"),"\n\n")
    
    # Convert to data.table, add names, and return
    return(setnames(as.data.table(ret), expectedCols))
  }

  ## ELSE: 

  ## TODO: This will be wrong if there is a quoted comma
  simpleParse <- function(s, splitOn=funkyString) {
    unlist(
      lapply(strsplit(s, splitOn), function(splat) { 
        nms.inds <- seq(1, length(splat), by=2)
        vals.inds <- nms.inds+1
        ret <- splat[vals.inds]
        setattr(ret, "names", splat[nms.inds])
        return(ret)
      })
    )
  } 



  ## Split on commas
  funkyString <- "@@~:~@@"
  headerSplit <- ":\\s*"
  commaSplit  <- ", "   # ideally, use lastComma <- "(.,)*., "
  
  ## Split the fields appart
  x2  <- strsplit(x, commaSplit) 

  ## Correct erroneous splits
  ## -------------------------
    ## Find those with too many splits
    lengths <- sapply(x2, length)
    tooMany <- lengths > mean(lengths)

    if (any(tooMany)) 
      x2[tooMany] <- 
        ## Paste back those which do not have a split. 
        lapply(x2[tooMany], function(ss) {
          toPaste <- (-1) + which(!sapply(ss, grepl, pattern=headerSplit, fixed=FALSE))
          ## Error check
          if(is.infinite(toPaste) || length(toPaste)==0) {cat("\nissue at \n\t", paste0(ss, collapse="\n\t"), "\n\n", sep=""); stop("Issue parsing.")}
          ## Paste it
          ss[[toPaste]] <- paste(ss[toPaste:(toPaste+1)], collapse=commaSplit)
          ## Remove the stragler
          ss <- ss[- (toPaste+1) ]
          return(ss)
        })
  ## -------------------------


  x2  <- lapply(x2, function(xx) sub(headerSplit, funkyString, xx))
  ret <- lapply(x2, simpleParse, splitOn=funkyString)

  as.data.table(do.call(rbind, ret))
}
