factored out common code