factor out the recursive stuff