Tried to do some abstraction, not perfect