Hopefully functional finished version; please test