added abstract factory