generalized the factory