a little refinement
can throw exception