This is business logic, and should be in the model layer