part 1 and some of part 2 is implemented but not tested