first working implementation. Still not complete though