Code largely rewritten