version 4 with generic private function