Rewritten almost from scratch