implement #8 and Add some tests