generalized to handle multiple loop levels