Switch to class-based structure, add support for custom actions