Total rewrite: the code is now divided into more parts