done, needs testing and polish