let deanonymize klass_data sast_klasses =
    let is_empty = function
        | [] -> true
        | _ -> false in

    let rec run_deanon init_state asts sasts = match asts, sasts with
        (* Every sAST has been deanonymized, even the deanonymized ones converted into sASTs
         * Every Ast has been sAST'd too. So we are done.
         *)

        | [], [] ->
            if is_empty init_state.deanon then Left((init_state.data, init_state.clean))
            else raise(Failure("Deanonymization somehow did not recurse properly."))

        | [], klass::rest ->
            let (asts, state) = deanon_class init_state klass in
            run_deanon state asts rest

        | klass::rest, _ -> match KlassData.append_leaf init_state.data klass with
            | Left(data) ->
                let sast_klass = BuildSast.ast_to_sast_klass data klass in
                let state = { init_state with data = data } in
                run_deanon state rest (sast_klass::sasts)
            | Right(issue) -> Right(issue) in

    run_deanon (empty_deanon_state klass_data) [] sast_klasses