First working version. Still needs a lot of refinement.