final version after some cleaning up and improvements