DRY'd up client logic