public function call(
        string $method,
        array &$arguments = [],
        string $callType = Caller::TYPE_DEFAULT,
        $result = null,
        bool $catchHalt = true
    ) {
        $done = false;
        $this->each(function ($middleware, $key) use (&$done, &$method, &$arguments, $callType, &$result, $catchHalt) {
            if ($done) {
                return;
            }

            $before = $result;
            if ($result === null && $middleware instanceof MiddlewareInterface) {
                $context = $middleware->getContext();
                if (is_object($context)) {
                    $result = $context;
                    $before = clone $context;
                }
            }

            if ($method) {
                if ($middleware instanceof static) {
                    $result = $middleware->call($method, $arguments, $callType, $result, $catchHalt);
                } elseif ($middleware) {
                    $result = (new Caller($middleware, $result))
                        ->as($callType)
                        ->catch($catchHalt)
                        ->call($method, $arguments);
                }
            }

            if ($this->callContextChanged($callType, $before, $result)) {
                $done = true;
            }
        });
        return $result;
    }