lots of restructuring, add recursion helper