Added most of the implementation