public function set($key, $value = null)
    {
        i\type_check($key, ['array', 'string']);

        if (func_num_args() === 1 && is_string($key)) {
            throw new BadMethodCallException(sprintf(
                "Too few arguments to method %s::%s(). If first argument is a string, a second argument is required",
                __CLASS__,
                __FUNCTION__
            ));
        }

        $input = func_num_args() === 1 ? (array)$key : [$key => $value];

        /** @var Event\BeforeSet $event */
        $event = $this->dispatchEvent(new Event\BeforeSet($this, $input));
        $data = $event->getPayload();

        object_set_properties($this, $data, $this instanceof DynamicEntity);

        $this->dispatchEvent(new Event\AfterSet($this, $data));

        return $this;
    }