Tested and mostly working final version