protected function parseURI($uri, $relative)
    {
        $result = array();

        if (!$relative) {
            // Parse scheme.
            $pos = strpos($uri, ':');
            if (!$pos) {
                // An URI starting with ":" is also invalid.
                throw new \InvalidArgumentException('No scheme found');
            }

            $result['scheme'] = substr($uri, 0, $pos);
            $uri = (string) substr($uri, $pos + 1);
        }

        // Parse fragment.
        $pos = strpos($uri, '#');
        if ($pos !== false) {
            $result['fragment'] = (string) substr($uri, $pos + 1);
            $uri = (string) substr($uri, 0, $pos);
        }

        // Parse query string.
        $pos = strpos($uri, '?');
        if ($pos !== false) {
            $result['query'] = (string) substr($uri, $pos + 1);
            $uri = (string) substr($uri, 0, $pos);
        }

        // Handle "path-empty".
        if ($uri == '') {
            $result['path'] = '';
            return $result;
        }

        // Handle "hier-part".
        if (substr($uri, 0, 2) == '//') {
            // Remove leftovers from the scheme field.
            $uri = (string) substr($uri, 2);

            // Parse path.
            $result['path'] = '';
            $pos = strpos($uri, '/');
            if ($pos !== false) {
                $result['path'] = substr($uri, $pos);
                $uri = (string) substr($uri, 0, $pos);
            }

            // Parse userinfo.
            $pos = strpos($uri, '@');
            if ($pos !== false) {
                $result['userinfo'] = (string) substr($uri, 0, $pos);
                $uri = (string) substr($uri, $pos + 1);
            }

            // Parse port.
            $rpos   = strcspn(strrev($uri), ':]');
            $len    = strlen($uri);
            if ($rpos != 0 && $rpos < $len && $uri[$len - $rpos - 1] != "]") {
                $result['port'] = (string) substr($uri, -1 * $rpos);
                $uri = (string) substr($uri, 0, -1 * $rpos - 1);
            }

            $result['host'] = $uri;
            return $result;
        }

        // Handle "path-absolute" & "path-rootless".
        $result['path'] = $uri;
        return $result;
    }