protected function validatePath($path, $relative)
    {
        /*
        path          = path-abempty    ; begins with "/" or is empty
                      / path-absolute   ; begins with "/" but not "//"
                      / path-noscheme   ; begins with a non-colon segment
                      / path-rootless   ; begins with a segment
                      / path-empty      ; zero characters
        path-abempty  = *( "/" segment )
        path-absolute = "/" [ segment-nz *( "/" segment ) ]
        path-noscheme = segment-nz-nc *( "/" segment )
                      ; only used for a relative URI
        path-rootless = segment-nz *( "/" segment )
                      ; only used for an absolute URI
        path-empty    = 0<pchar>
        segment       = *pchar
        segment-nz    = 1*pchar
        segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
                      ; non-zero-length segment without any colon ":"
        pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
        unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
        sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
                      / "*" / "+" / "," / ";" / "="
        pct-encoded   = "%" HEXDIG HEXDIG
        */
        $pchar          =   '(?:'.
                                '[-[:alnum:]\\._~!\\$&\'\\(\\)\\*\\+,;=:@]|'.
                                '%[[:xdigit:]]'.
                            ')';
        $segment        = '(?:'.$pchar.'*)';
        $segmentNz      = '(?:'.$pchar.'+)';
        $segmentNzNc    =   '(?:'.
                                '[-[:alnum:]\\._~!\\$&\'\\(\\)\\*\\+,;=@]|'.
                                '%[[:xdigit:]]'.
                            ')+';
        $pathAbempty    = '(?:/'.$segment.')*';
        $pathAbsolute   = '/(?:'.$segmentNz.'(?:/'.$segment.')*)?';
        $pathNoscheme   = $segmentNzNc.'(?:/'.$segment.')*';
        $pathRootless   = $segmentNz.'(?:/'.$segment.')*';
        $pathEmpty      = '(?!'.$pchar.')';

        $pattern = '(?:' . $pathAbempty.'|'.$pathAbsolute;
        if ($relative) {
            $pattern .= '|'.$pathNoscheme;
        } else {
            $pattern .= '|'.$pathRootless;
        }
        $pattern .= '|'.$pathEmpty . ')';

        return (bool) preg_match('#^'.$pattern.'$#Di', $path);
    }