Tentatively finished version. Messy code