complete but need to refactor