final implementation with bugs