let make_extensions ts =
  let childmap =
    List.map (
      fun (name, _, t) ->
        (* Find the children of this type. *)
        let children = List.filter (
          function
            | (_, _, Extension (basename, _))
                when to_string basename = name -> true
            | _ -> false
        ) ts in
        let children = List.map (
          function
            | (childname, _, Extension (_, _)) -> childname
            | _ -> assert false
        ) children in
        ((name, children) : string * string list)
    ) ts in
  (* Combine extensions with their base type. *)
  let ts =
    let rec build_type extname basename exttype =
      (* Find the base type. *)
      let _, _, basetype =
        try List.find (
          function
            | (name, _, t) when name = basename -> true
            | _ -> false
        ) ts
        with Not_found -> failwith ("extension type " ^ extname ^
                                    " refers to base type " ^ basename ^
                                    " which cannot be found"in
      (* Get the base type, eg. a sequence. *)
      let basetype =
        match basetype with
          | Extension (basename, exttype) ->
              build_type extname (to_string basename) exttype
          | t -> t in
      (* Extend the base type. *)
      match basetype, exttype with
        | (Enumeration elements, Enumeration elements') ->
            Enumeration (elements @ elements')
        | (Sequence elements, Sequence elements') ->
            Sequence (elements @ elements')
        | _ ->
            failwith ("extension type " ^ extname ^ " is/extends something " ^
                      "which is not an enumeration or sequence of the same " ^
                      "type.")
    in

    List.map (
      function
        | (name, is_abstract, Extension (basename, exttype)) ->
            let t = build_type name (to_string basename) exttype in
            name, is_abstract, t
        | t -> t
    ) ts in

  ts, childmap