Not DRY, but it works