better code design, some refactoring still needed