almost there... but needs some refactoring