Step 3, functional. Needs cleanup