implemented so far, needs some refactoring