final public function &__invoke(object $instance, int $accessType, &$originalValue, $newValue = NAN)
    {
        if ($this->level > 0) {
            $this->stackFrames[] = [$this->instance, $this->accessType, &$this->value, &$this->newValue];
        }

        try {
            ++$this->level;

            $this->current    = 0;
            $this->instance   = $instance;
            $this->accessType = $accessType;
            $this->value      = &$originalValue;
            $this->newValue   = $newValue;

            $this->proceed();

            if ($accessType === self::READ) {
                $result = &$this->value;
            } else {
                $result = &$this->newValue;
            }

            return $result;
        } finally {
            --$this->level;

            if ($this->level > 0) {
                [$this->instance, $this->accessType, $this->value, $this->newValue] = array_pop($this->stackFrames);
            }
        }
    }