rewrite using S4 classes