split optimization steps into separate implementations