Complete functional version