/// <summary>
        /// Create the external version of a uri
        /// </summary>
        private static string _asFormatted(DocumentUri uri, bool skipEncoding)
        {
            string Encoder(string p, bool allowSlash)
            {
                return(!skipEncoding?EncodeUriComponentFast(p, allowSlash) : EncodeUriComponentMinimal(p));
            }

            var res = "";

            var(scheme, authority, path, query, fragment) = uri;
            if (!string.IsNullOrWhiteSpace(scheme))
            {
                res += scheme;
                res += ":";
            }

            if (!string.IsNullOrWhiteSpace(authority) || scheme == "file")
            {
                res += Slash;
                res += Slash;
            }

            if (!string.IsNullOrWhiteSpace(authority))
            {
                var idx = authority.IndexOf("@");
                if (idx != -1)
                {
                    // <user>@<auth>
                    var userinfo = authority.Substring(0, idx);
                    authority = authority.Substring(idx + 1);
                    idx       = userinfo.IndexOf(":");
                    if (idx == -1)
                    {
                        res += Encoder(userinfo, false);
                    }
                    else
                    {
                        // <user>:<pass>@<auth>
                        res += Encoder(userinfo.Substring(0, idx), false);
                        res += ":";
                        res += Encoder(userinfo.Substring(idx + 1), false);
                    }

                    res += "@";
                }

                authority = authority.ToLowerInvariant();
                idx       = authority.IndexOf(":", StringComparison.Ordinal);
                if (idx == -1)
                {
                    res += Encoder(authority, false);
                }
                else
                {
                    // <auth>:<port>
                    res += Encoder(authority.Substring(0, idx), false);
                    res += authority.Substring(idx);
                }
            }

            if (!string.IsNullOrWhiteSpace(path))
            {
                // lower-case windows drive letters in /C:/fff or C:/fff
                if (path.Length >= 3 && path[0] == CharCode.Slash && path[2] == CharCode.Colon)
                {
                    var code = path[1];
                    if (code >= CharCode.A && code <= CharCode.Z)
                    {
                        path = $"/{Convert.ToChar(code + 32)}:{path.Substring(3)}"; // "/c:".length == 3
                    }
                }
                else if (path.Length >= 2 && path[1] == CharCode.Colon)
                {
                    var code = path[0];
                    if (code >= CharCode.A && code <= CharCode.Z)
                    {
                        path = $"{Convert.ToChar(code + 32)}:{path.Substring(2)}"; // "/c:".length == 3
                    }
                }

                // encode the rest of the path
                res += Encoder(path, true);
            }

            if (!string.IsNullOrWhiteSpace(query))
            {
                res += "?";
                res += Encoder(query, false);
            }

            if (!string.IsNullOrWhiteSpace(fragment))
            {
                res += "#";
                res += !skipEncoding?EncodeUriComponentFast(fragment, false) : fragment;
            }

            return(res);
        }