public static function walk($collection, $key, $default = null)
    {
        if (is_null($key)) {
            return $collection;
        }
        if (is_string($key) && mb_substr($key, 0, 1) == '@') {
            if (Support::keyExists($collection, mb_substr($key, 1))) {
                return $collection[mb_substr($key, 1)];
            }

            return Support::value($default);
        }

        $key = is_array($key) ? $key : explode('.', $key);

        while (!is_null($segment = array_shift($key))) {
            if ($segment === '*') {
                if ($collection instanceof Collection) {
                    $collection = $collection->all();
                } elseif (!is_array($collection)) {
                    return Support::value($default);
                }

                $result = static::extract($collection, $key, null, $default);

                return in_array('*', $key) ? Support::flatten($result) : $result;
            }

            if (Support::isTraversable($collection) && Support::keyExists($collection, $segment)) {
                $collection = $collection[$segment];
            } elseif (is_object($collection) && isset($collection->{$segment})) {
                $collection = $collection->{$segment};
            } elseif (is_object($collection) && !($collection instanceof Collection) && method_exists($collection, $segment)) {
                $collection = $collection->{$segment}();
            } elseif (is_object($collection) && !($collection instanceof Collection) && method_exists($collection, 'get' . ucwords($segment))) {
                $collection = $collection->{'get' . ucwords($segment)}();
            } else {
                return Support::value($default);
            }
        }

        return $collection;
    }