public static function create($url, array $config = null, DispatcherInterface $dispatcher = null)
    {
        if (!($url instanceof Url)) {
            $url = Url::create($url);
        }

        if ($config === null) {
            $config = self::$default_config;
        } else {
            $config += self::$default_config;
        }

        if ($dispatcher === null) {
            $dispatcher = new CurlDispatcher();
        }

        $info = self::process($url, $config, $dispatcher);

        if ($info->getConfig('follow_canonical') === false) {
            return $info;
        }

        // Repeat the process if:
        // - The canonical url is different
        // - No embed code has found
        $from = preg_replace('|^(\w+://)|', '', rtrim((string)$info->getResponse()->getUrl(), '/'));
        $to = preg_replace('|^(\w+://)|', '', rtrim($info->url, '/'));

        if ($from !== $to && empty($info->code)) {
            //accept new result if valid
            try {
                return self::process(Url::create($info->url), $config, $dispatcher);
            } catch (\Exception $e) {
                return $info;
            }
        }

        return $info;
    }