Copied and adapted from Oso (https://github.com/osohq/oso/)
