refactored so the inner loop can be swapped out easily