Almost done. Need comments and heavy testing