generic factory (not finished yet)