protected function marshalQueryAndFragment($string): string
    {
        if ( ! is_string($string) ) {
            throw new UriException(
                'Query and Fragment must be a string or null'
            );
        }

        return preg_replace_callback(
            '/(?:[^'.self::$unreservedCharacters.self::$subDelimitedCharacters.'%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
            function($match) {
                return rawurlencode($match[0]);
            },
            $string
        );
    }