This function and everything below is new, everything above was moved and minimally changed