almost finished, remains to be debugged