Tested code. Not complete