long code ... difficult to understand !