implements #5 and fix some bugs