corrected version with tests