Major revision: generalized a lot