complete algortithm - untested