this class looks complicated, but we do not have time ;]