complete code, works exact same as v1.0