add factory and unit tests