private void DigestURI(URI uri)
 {
     this.scheme = uri.GetScheme();
     this.encodedSchemeSpecificPart = uri.GetRawSchemeSpecificPart();
     this.encodedAuthority          = uri.GetRawAuthority();
     this.host            = uri.GetHost();
     this.port            = uri.GetPort();
     this.encodedUserInfo = uri.GetRawUserInfo();
     this.userInfo        = uri.GetUserInfo();
     this.encodedPath     = uri.GetRawPath();
     this.path            = uri.GetPath();
     this.encodedQuery    = uri.GetRawQuery();
     this.queryParams     = ParseQuery(uri.GetRawQuery(), Consts.Utf8);
     this.encodedFragment = uri.GetRawFragment();
     this.fragment        = uri.GetFragment();
 }
        /// <summary>
        /// Removes dot segments according to RFC 3986, section 5.2.4 and
        /// Syntax-Based Normalization according to RFC 3986, section 6.2.2.
        /// </summary>
        /// <remarks>
        /// Removes dot segments according to RFC 3986, section 5.2.4 and
        /// Syntax-Based Normalization according to RFC 3986, section 6.2.2.
        /// </remarks>
        /// <param name="uri">the original URI</param>
        /// <returns>the URI without dot segments</returns>
        private static URI NormalizeSyntax(URI uri)
        {
            if (uri.IsOpaque() || uri.GetAuthority() == null)
            {
                // opaque and file: URIs
                return(uri);
            }
            Args.Check(uri.IsAbsolute(), "Base URI must be absolute");
            string path = uri.GetPath() == null ? string.Empty : uri.GetPath();

            string[]       inputSegments  = path.Split("/");
            Stack <string> outputSegments = new Stack <string>();

            foreach (string inputSegment in inputSegments)
            {
                if ((inputSegment.Length == 0) || (".".Equals(inputSegment)))
                {
                }
                else
                {
                    // Do nothing
                    if ("..".Equals(inputSegment))
                    {
                        if (!outputSegments.IsEmpty())
                        {
                            outputSegments.Pop();
                        }
                    }
                    else
                    {
                        outputSegments.Push(inputSegment);
                    }
                }
            }
            StringBuilder outputBuffer = new StringBuilder();

            foreach (string outputSegment in outputSegments)
            {
                outputBuffer.Append('/').Append(outputSegment);
            }
            if (path.LastIndexOf('/') == path.Length - 1)
            {
                // path.endsWith("/") || path.equals("")
                outputBuffer.Append('/');
            }
            try
            {
                string scheme = uri.GetScheme().ToLower();
                string auth   = uri.GetAuthority().ToLower();
                URI    @ref   = new URI(scheme, auth, outputBuffer.ToString(), null, null);
                if (uri.GetQuery() == null && uri.GetFragment() == null)
                {
                    return(@ref);
                }
                StringBuilder normalized = new StringBuilder(@ref.ToASCIIString());
                if (uri.GetQuery() != null)
                {
                    // query string passed through unchanged
                    normalized.Append('?').Append(uri.GetRawQuery());
                }
                if (uri.GetFragment() != null)
                {
                    // fragment passed through unchanged
                    normalized.Append('#').Append(uri.GetRawFragment());
                }
                return(URI.Create(normalized.ToString()));
            }
            catch (URISyntaxException e)
            {
                throw new ArgumentException(e);
            }
        }