let create 
  ?(failsafe = Ignore
  ?(categories = []) 
  ?(codesets = [])
  ?(dirs = []) 
  ?(textdomains = [])
  ?(codeset = GettextConfig.default_codeset )
  ?(path = GettextConfig.default_path )
  ?(language)
  textdomain =
    let map_categories = 
        List.fold_left ( 
          fun map (category,locale) -> 
            MapCategory.add category locale map 
          ) 
        MapCategory.empty
        categories
    in
    let result =
      {
        failsafe    = failsafe;
        textdomains = MapTextdomain.empty;
        categories  = map_categories;
        language    = language;
        codeset     = codeset;
        path        = path;
        default     = textdomain;
      }
    in
    (* Apply any upgrade required by the different settings provided *)
    let apply_upgrade t lst =
      List.fold_left (
        fun t (textdomain,changes) ->
          upgrade_textdomain t textdomain changes
      ) t lst
    in
    (* All changes from the setting of textdomains *)
    let textdomains_changes = 
      List.map 
      (fun textdomain -> (textdomain,(None,None))) 
      (textdomain :: textdomains)
    in
    (* All changes from the setting of codesets *)
    let codesets_changes =
      List.map 
      (fun (textdomain,codeset) -> (textdomain,(Some codeset,None))) 
      codesets
    in
    (* All changes from the setting of dirs *)
    let dirs_changes =
      List.map 
      (fun (textdomain,dir) -> (textdomain,(None,Some dir))) 
      dirs
    in
    apply_upgrade 
    result 
    ( textdomains_changes @ codesets_changes @ dirs_changes )