fully working, may still have bugs