let output_mo ?(endianess = LittleEndian) chn lst =
  (* There could have potential issue with alignment, but it seems to be fixed
  * at 1 in gettext-0.14.1/gettext-tools/configure.ac, so there is no probleme
  * *)

  let null_terminated lst = 
    List.map ( fun str -> str^"\000" ) lst
  in
  let compute_table start_pos lst = 
    let compute_length lst = 
      List.map String.length lst
    in
    let compute_offset (current_pos,lst_pos) length = 
      (* Remove 1 since we have NULL terminated strings *)
      ( current_pos + length, (length - 1,current_pos) :: lst_pos )
    in
    let (final_pos, lst_rev) = 
      List.fold_left compute_offset (start_pos, []) (compute_length lst)
    in
    (final_pos, List.rev lst_rev)
  in
  let sorted_lst = 
    let compare_entry entry1 entry2 = 
      let value_of_entry entry = 
        match entry with 
          Singular (id, _) -> id
        | Plural (id, _, _) -> id
      in
      String.compare ( value_of_entry entry1) (value_of_entry entry2)
    in
    List.sort compare_entry lst
  in
  let untranslated = 
    let to_string entry = 
      match entry with
        Singular (id, _) -> id
      | Plural (id, id_plural, _) -> id ^ "\000" ^ id_plural
    in
    null_terminated (List.map to_string sorted_lst)
  in
  let translated = 
    let to_string entry = 
      match entry with
        Singular (_,str) -> str
      | Plural (_, _, lst) -> String.concat "\000" lst
    in
    null_terminated (List.map to_string sorted_lst)
  in
  let gN = List.length lst
  in
  let gO = 28 (* Size of the header *)
  in
  let gT = gO + 8 * gN
  in
  let gS = 0 (* Hashtable is not implemented, since algorithm is not public -- documented *)
  in
  let gH = gT + 8 * gN
  in
  let (final_untranslated,untranslated_table) = 
    compute_table (gH + gS * 4) untranslated
  in
  let (_,translated_table) = 
    compute_table final_untranslated translated
  in
  let header = {
    endianess                = endianess;
    file_format_revision     = Int32.zero;
    number_of_strings        = Int32.of_int gN;
    offset_table_strings     = Int32.of_int gO;
    offset_table_translation = Int32.of_int gT;
    size_of_hashing_table    = Int32.of_int gS;
    offset_of_hashing_table  = Int32.of_int gH;
  }
  in
  output_mo_header chn header;
  List.iter (
    List.iter (
      fun (a,b) -> 
        output_int32_pair chn endianess (Int32.of_int a,Int32.of_int b);
      ) 
  ) [ untranslated_table ; translated_table ];
  List.iter (output_string chn) untranslated;
  List.iter (output_string chn) translated