guess_substr_info <- function(x, dic, mapping = NULL) {

  if (is.null(mapping)) {
    path    <- system.file("extdata", "etcsl_mapping.txt", package = "sumer")
    mapping <- read.csv2(path, sep = ";", na.strings = "")
  }

  # Convert dic to a list of dictionaries
  if (is.character(dic)) {
    dic <- lapply(dic, read_dictionary, verbose = FALSE)
  } else if (is.data.frame(dic)) {
    dic <- list(dic)
  }

  # Extract tokens
  token <- split_sumerian(as.cuneiform(x, mapping = mapping))$signs
  N     <- length(token)

  # Initialize empty substring data frame
  df <- init_substr_info(token)

  # Add sign name column
  df$sign_name <- as.sign_name(df$expr, mapping = mapping)

  # For each row: look up the most frequent translation
  for (i in seq_len(nrow(df))) {
    for (d in dic) {
      rows <- d[d$sign_name == df$sign_name[i] & d$row_type == "trans.", , drop = FALSE]
      if (nrow(rows) > 0) {
        if (all(is.na(rows$count))) {
          best <- rows[1, ]
        } else {
          best <- rows[which.max(rows$count), ]
        }
        df$type[i]        <- best$type
        df$translation[i] <- best$meaning
        break
      }
    }
  }

  # Zahlen und N: type -> "S", translation -> Wert aus expr
  sp <- split_sumerian(as.cuneiform(x, mapping = mapping))
  for (i in seq_len(nrow(df))) {
    if (df$n_tokens[i] != 1L) next
    tok_type <- sp$types[df$start[i]]
    if (tok_type == 4L) {
      df$type[i]        <- "S"
      df$translation[i] <- sp$signs[df$start[i]]
    }
  }

  df
}
