reorganized to separate reusable part