refactor for perform()