copied from the excellent work of daniel Berteaud