full of ugly code, but it works