rewrite to provide a non-recursive api