re-write into abstract class