main abstraction