implement most stuff (untested)