updated for the general case