refactor to support iterate