diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9dad712
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+[Bb]in
+[Oo]bj
+.idea
\ No newline at end of file
diff --git a/DotNetFrameworkUriEscaping.csproj b/DotNetFrameworkUriEscaping.csproj
new file mode 100644
index 0000000..a051af2
--- /dev/null
+++ b/DotNetFrameworkUriEscaping.csproj
@@ -0,0 +1,9 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <TargetFramework>netstandard2.0</TargetFramework>
+    <LangVersion>11</LangVersion>
+    <PackageId>DotNetFrameworkUriEscaping</PackageId>
+    <Version>1.0.0.0</Version>
+  </PropertyGroup>
+</Project>
diff --git a/System/net/System/NetFrameworkUri.cs b/System/net/System/NetFrameworkUri.cs
new file mode 100644
index 0000000..03a458b
--- /dev/null
+++ b/System/net/System/NetFrameworkUri.cs
@@ -0,0 +1,295 @@
+using System;
+using System.Text;
+
+namespace DotNetFrameworkUriEscaping;
+
+/// <summary>
+/// hugheshilton@:
+/// This class contains the original .NET Framework source for Uri.GetDataString() executed in V2 quirks mode. Other
+/// than minor style changes made by Rider and changes to references to make these methods use their own versions
+/// of methods and constants, these methods are copy/pasted here unchanged from the original versions.
+///
+/// The one modification I did was to force the use of V2 quirks mode in s_QuirksVersion. Originally, whether V2 or V3
+/// quirks mode was used was controlled by a compilation symbol so it was slightly unclear which was being used.
+/// However, once I tested this, it became clear that V2 quirks mode was used since V3 quirks mode escaped the '('
+/// and ')' characters just like .NET Core does. Since we need this code to behave like .NET Framework, V2 quirks
+/// mode is what we need.
+///
+/// I'm leaving the original files I copied these methods from with all code commented out in case we ever need to
+/// compare or fix something in these methods from the original source.
+/// </summary>
+public static class NetFrameworkUri
+{
+    internal const char
+        c_DummyChar = (char)0xFFFF; //An Invalid Unicode character used as a dummy char passed into the parameter
+    
+    const short c_MaxAsciiCharsReallocate = 40;
+    const short c_MaxUnicodeCharsReallocate = 40;
+    const short c_MaxUTF_8BytesPerUnicodeChar = 4;
+    const short c_EncodedCharsPerByte = 3;
+    
+    internal const int c_MaxUriBufferSize = 0xFFF0;
+    internal const string RFC3986ReservedMarks = @";/?:@&=+$,#[]!'()*";
+    
+    private const string RFC2396ReservedMarks = @";/?:@&=+$,";
+    private const string RFC3986UnreservedMarks = @"-_.~";
+    private const string RFC2396UnreservedMarks = @"-_.~*'()!";
+    
+    private static readonly char[] HexUpperChars =
+    {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+    
+    private enum UriQuirksVersion
+    {
+        // V1 = 1, // RFC 1738 - Not supported
+        V2 = 2, // RFC 2396
+        V3 = 3, // RFC 3986, 3987
+    }
+
+    // (hugheshilton@): Although it's not super clear from the original .NET Framework source which version of quirks
+    // to use, testing makes it clear that we were using V2 quirks since that's the version that does not escape
+    // '(' and ')' in query strings.
+    private static readonly UriQuirksVersion s_QuirksVersion = UriQuirksVersion.V2;
+
+    internal static bool ShouldUseLegacyV2Quirks
+    {
+        get { return s_QuirksVersion <= UriQuirksVersion.V2; }
+    }
+    
+    //
+    // Where stringToEscape is intended to be URI data, but not an entire URI.
+    // This method will escape any character that is not an unreserved character, including percent signs.
+    //
+    public static string EscapeDataString(string stringToEscape)
+    {
+        if (stringToEscape == null)
+            throw new ArgumentNullException("stringToEscape");
+
+        if (stringToEscape.Length == 0)
+            return string.Empty;
+
+        int position = 0;
+        char[] dest = EscapeString(stringToEscape, 0, stringToEscape.Length, null, ref position, false,
+            c_DummyChar, c_DummyChar, c_DummyChar);
+        if (dest == null)
+            return stringToEscape;
+        return new string(dest, 0, position);
+    }
+    
+    internal unsafe static char[] EscapeString(string input, int start, int end, char[] dest, ref int destPos,
+        bool isUriString, char force1, char force2, char rsvd)
+    {
+        if (end - start >= c_MaxUriBufferSize)
+            throw new UriFormatException("Max uri size limit exceeded.");
+
+        int i = start;
+        int prevInputPos = start;
+        byte* bytes = stackalloc byte[c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar]; // 40*4=160
+
+        fixed (char* pStr = input)
+        {
+            for (; i < end; ++i)
+            {
+                char ch = pStr[i];
+
+                // a Unicode ?
+                if (ch > '\x7F')
+                {
+                    short maxSize = (short)Math.Min(end - i, (int)c_MaxUnicodeCharsReallocate - 1);
+
+                    short count = 1;
+                    for (; count < maxSize && pStr[i + count] > '\x7f'; ++count)
+                        ;
+
+                    // Is the last a high surrogate?
+                    if (pStr[i + count - 1] >= 0xD800 && pStr[i + count - 1] <= 0xDBFF)
+                    {
+                        // Should be a rare case where the app tries to feed an invalid Unicode surrogates pair
+                        if (count == 1 || count == end - i)
+                            throw new UriFormatException("Invalid unicode string.");
+                        // need to grab one more char as a Surrogate except when it's a bogus input
+                        ++count;
+                    }
+
+                    dest = EnsureDestinationSize(pStr, dest, i,
+                        (short)(count * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte),
+                        c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte,
+                        ref destPos, prevInputPos);
+
+                    short numberOfBytes = (short)Encoding.UTF8.GetBytes(pStr + i, count, bytes,
+                        c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar);
+
+                    // This is the only exception that built in UriParser can throw after a Uri ctor.
+                    // Should not happen unless the app tries to feed an invalid Unicode String
+                    if (numberOfBytes == 0)
+                        throw new UriFormatException("Invalid unicode string.");
+
+                    i += (count - 1);
+
+                    for (count = 0; count < numberOfBytes; ++count)
+                        EscapeAsciiChar((char)bytes[count], dest, ref destPos);
+
+                    prevInputPos = i + 1;
+                }
+                else if (ch == '%' && rsvd == '%')
+                {
+                    // Means we don't reEncode '%' but check for the possible escaped sequence
+                    dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+                        c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+                    if (i + 2 < end && EscapedAscii(pStr[i + 1], pStr[i + 2]) != c_DummyChar)
+                    {
+                        // leave it escaped
+                        dest[destPos++] = '%';
+                        dest[destPos++] = pStr[i + 1];
+                        dest[destPos++] = pStr[i + 2];
+                        i += 2;
+                    }
+                    else
+                    {
+                        EscapeAsciiChar('%', dest, ref destPos);
+                    }
+
+                    prevInputPos = i + 1;
+                }
+                else if (ch == force1 || ch == force2)
+                {
+                    dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+                        c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+                    EscapeAsciiChar(ch, dest, ref destPos);
+                    prevInputPos = i + 1;
+                }
+                else if (ch != rsvd && (isUriString ? !IsReservedUnreservedOrHash(ch) : !IsUnreserved(ch)))
+                {
+                    dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+                        c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+                    EscapeAsciiChar(ch, dest, ref destPos);
+                    prevInputPos = i + 1;
+                }
+            }
+
+            if (prevInputPos != i)
+            {
+                // need to fill up the dest array ?
+                if (prevInputPos != start || dest != null)
+                    dest = EnsureDestinationSize(pStr, dest, i, 0, 0, ref destPos, prevInputPos);
+            }
+        }
+
+        return dest;
+    }
+    
+    //
+    // ensure destination array has enough space and contains all the needed input stuff
+    //
+    private unsafe static char[] EnsureDestinationSize(char* pStr, char[] dest, int currentInputPos,
+        short charsToAdd, short minReallocateChars, ref int destPos, int prevInputPos)
+    {
+        if ((object)dest == null || dest.Length < destPos + (currentInputPos - prevInputPos) + charsToAdd)
+        {
+            // allocating or reallocating array by ensuring enough space based on maxCharsToAdd.
+            char[] newresult = new char[destPos + (currentInputPos - prevInputPos) + minReallocateChars];
+
+            if ((object)dest != null && destPos != 0)
+                Buffer.BlockCopy(dest, 0, newresult, 0, destPos << 1);
+            dest = newresult;
+        }
+
+        // ensuring we copied everything form the input string left before last escaping
+        while (prevInputPos != currentInputPos)
+            dest[destPos++] = pStr[prevInputPos++];
+        return dest;
+    }
+    
+    internal static void EscapeAsciiChar(char ch, char[] to, ref int pos)
+    {
+        to[pos++] = '%';
+        to[pos++] = HexUpperChars[(ch & 0xf0) >> 4];
+        to[pos++] = HexUpperChars[ch & 0xf];
+    }
+    
+    internal static char EscapedAscii(char digit, char next)
+    {
+        if (!(((digit >= '0') && (digit <= '9'))
+              || ((digit >= 'A') && (digit <= 'F'))
+              || ((digit >= 'a') && (digit <= 'f'))))
+        {
+            return c_DummyChar;
+        }
+
+        int res = (digit <= '9')
+            ? ((int)digit - (int)'0')
+            : (((digit <= 'F')
+                   ? ((int)digit - (int)'A')
+                   : ((int)digit - (int)'a'))
+               + 10);
+
+        if (!(((next >= '0') && (next <= '9'))
+              || ((next >= 'A') && (next <= 'F'))
+              || ((next >= 'a') && (next <= 'f'))))
+        {
+            return c_DummyChar;
+        }
+
+        return (char)((res << 4) + ((next <= '9')
+            ? ((int)next - (int)'0')
+            : (((next <= 'F')
+                   ? ((int)next - (int)'A')
+                   : ((int)next - (int)'a'))
+               + 10)));
+    }
+    
+    private static unsafe bool IsReservedUnreservedOrHash(char c)
+    {
+        if (IsUnreserved(c))
+        {
+            return true;
+        }
+
+        if (ShouldUseLegacyV2Quirks)
+        {
+            return ((RFC2396ReservedMarks.IndexOf(c) >= 0) || c == '#');
+        }
+
+        return (RFC3986ReservedMarks.IndexOf(c) >= 0);
+    }
+    
+    internal static unsafe bool IsUnreserved(char c)
+    {
+        if (IsAsciiLetterOrDigit(c))
+        {
+            return true;
+        }
+
+        if (ShouldUseLegacyV2Quirks)
+        {
+            return (RFC2396UnreservedMarks.IndexOf(c) >= 0);
+        }
+
+        return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
+    }
+
+    internal static bool Is3986Unreserved(char c)
+    {
+        if (IsAsciiLetterOrDigit(c))
+        {
+            return true;
+        }
+
+        return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
+    }
+    
+    internal static bool IsAsciiLetterOrDigit(char character)
+    {
+        return IsAsciiLetter(character) || (character >= '0' && character <= '9');
+    }
+    
+    //Only consider ASCII characters
+    private static bool IsAsciiLetter(char character)
+    {
+
+        return (character >= 'a' && character <= 'z') ||
+               (character >= 'A' && character <= 'Z');
+    }
+}
diff --git a/System/net/System/URI.cs b/System/net/System/URI.cs
index e264a1f..e14fc25 100644
--- a/System/net/System/URI.cs
+++ b/System/net/System/URI.cs
@@ -1,5518 +1,5518 @@
-//------------------------------------------------------------------------------
-// <copyright file="URI.cs" company="Microsoft">
-//     Copyright (c) Microsoft Corporation.  All rights reserved.
-// </copyright>
-//------------------------------------------------------------------------------
-
-namespace System {
-    using System.Runtime.InteropServices;
-    using System.Text;
-    using System.Globalization;
-    using System.Security;
-    using System.ComponentModel;
-    // Not in SL:
-    using System.Configuration;
-    using System.Security.Permissions;
-    using System.Runtime.Serialization;
-    using Microsoft.Win32;
-    using System.Threading;
-    using System.Diagnostics.CodeAnalysis;
-    using System.Net;
-    [Serializable]
-    [TypeConverter(typeof(UriTypeConverter))]
-    public partial class Uri : ISerializable {
-
-        public static readonly string UriSchemeFile = UriParser.FileUri.SchemeName;
-        public static readonly string UriSchemeFtp = UriParser.FtpUri.SchemeName;
-        public static readonly string UriSchemeGopher = UriParser.GopherUri.SchemeName;
-        public static readonly string UriSchemeHttp = UriParser.HttpUri.SchemeName;
-        public static readonly string UriSchemeHttps = UriParser.HttpsUri.SchemeName;
-        internal static readonly string UriSchemeWs = UriParser.WsUri.SchemeName;
-        internal static readonly string UriSchemeWss = UriParser.WssUri.SchemeName;
-        public static readonly string UriSchemeMailto = UriParser.MailToUri.SchemeName;
-        public static readonly string UriSchemeNews = UriParser.NewsUri.SchemeName;
-        public static readonly string UriSchemeNntp = UriParser.NntpUri.SchemeName;
-        public static readonly string UriSchemeNetTcp = UriParser.NetTcpUri.SchemeName;
-        public static readonly string UriSchemeNetPipe = UriParser.NetPipeUri.SchemeName;
-        public static readonly string SchemeDelimiter = "://";
-
-
-        private const int c_Max16BitUtf8SequenceLength = 3+3+3+3; //each unicode byte takes 3 escaped chars
-        internal const int c_MaxUriBufferSize = 0xFFF0;
-        private const int c_MaxUriSchemeName = 1024;
-
-        // untouched user string unless string has unicode chars and iriparsing is enabled
-        // or idn is on and we have unicode host or idn host
-        // In that case, this string is normalized, stripped of bidi chars, and validated
-        // with char limits
-        private string      m_String;
-
-        // untouched user string if string has unicode with iri on or unicode/idn host with idn on
-        private string      m_originalUnicodeString;
-
-        private UriParser m_Syntax;   // This is a whole Uri syntax, not only the scheme name
-        // temporarily stores dnssafe host when we have unicode/idn host and idn is on
-        private string m_DnsSafeHost = null;
-
-        [Flags]
-        private enum Flags : ulong {
-            Zero                = 0x00000000,
-
-            SchemeNotCanonical     = 0x1,
-            UserNotCanonical       = 0x2,
-            HostNotCanonical       = 0x4,
-            PortNotCanonical       = 0x8,
-            PathNotCanonical       = 0x10,
-            QueryNotCanonical      = 0x20,
-            FragmentNotCanonical   = 0x40,
-            CannotDisplayCanonical = 0x7F,
-
-            E_UserNotCanonical      = 0x80,
-            E_HostNotCanonical      = 0x100,
-            E_PortNotCanonical      = 0x200,
-            E_PathNotCanonical      = 0x400,
-            E_QueryNotCanonical     = 0x800,
-            E_FragmentNotCanonical  = 0x1000,
-            E_CannotDisplayCanonical = 0x1F80,
-
-
-            ShouldBeCompressed      = 0x2000,
-            FirstSlashAbsent        = 0x4000,
-            BackslashInPath         = 0x8000,
-
-            IndexMask           = 0x0000FFFF,
-            HostTypeMask        = 0x00070000,
-            HostNotParsed   = 0x00000000,
-            IPv6HostType    = 0x00010000,
-            IPv4HostType    = 0x00020000,
-            DnsHostType     = 0x00030000,
-#if !PLATFORM_UNIX
-            UncHostType     = 0x00040000,
-#endif // !PLATFORM_UNIX
-            BasicHostType   = 0x00050000,
-            UnusedHostType  = 0x00060000,
-            UnknownHostType = 0x00070000,
-
-            UserEscaped         = 0x00080000,
-            AuthorityFound      = 0x00100000,
-            HasUserInfo         = 0x00200000,
-            LoopbackHost        = 0x00400000,
-            NotDefaultPort      = 0x00800000,
-
-            UserDrivenParsing   = 0x01000000,
-            CanonicalDnsHost    = 0x02000000,
-            ErrorOrParsingRecursion = 0x04000000,   // Used to signal a default parser error and alsoe to confirm Port 
-                                                    // and Host values in case of a custom user Parser
-#if !PLATFORM_UNIX
-            DosPath             = 0x08000000,
-            UncPath             = 0x10000000,
-#endif // !PLATFORM_UNIX
-            ImplicitFile        = 0x20000000,
-            MinimalUriInfoSet   = 0x40000000,
-            AllUriInfoSet       = unchecked(0x80000000),
-            IdnHost             = 0x100000000,
-            HasUnicode          = 0x200000000,
-            HostUnicodeNormalized = 0x400000000,
-            RestUnicodeNormalized = 0x800000000,
-            UnicodeHost         = 0x1000000000,
-            IntranetUri         = 0x2000000000,
-            UseOrigUncdStrOffset= 0x4000000000,
-            // Is this component Iri canonical
-            UserIriCanonical =          0x8000000000,
-            PathIriCanonical =          0x10000000000,
-            QueryIriCanonical =         0x20000000000,
-            FragmentIriCanonical =      0x40000000000,
-            IriCanonical =              0x78000000000,
-        }
-
-        private Flags       m_Flags;
-        private UriInfo     m_Info;
-
-        private class UriInfo {
-            public string   Host;
-            public string   ScopeId;        //only IP v6 may need this
-            public string   String;
-            public Offset   Offset;
-            public string   DnsSafeHost;    // stores dns safe host when idn is on and we have unicode or idn host
-            public MoreInfo MoreInfo;       // Multi-threading: This field must be always accessed through a _local_ 
-                                            // stack copy of m_Info.
-        };
-
-        [StructLayout(LayoutKind.Sequential, Pack=1)]
-        private struct Offset {
-            public ushort  Scheme;
-            public ushort  User;
-            public ushort  Host;
-            public ushort  PortValue;
-            public ushort  Path;
-            public ushort  Query;
-            public ushort  Fragment;
-            public ushort  End;
-        };
-
-        private class MoreInfo {
-            public string   Path;
-            public string   Query;
-            public string   Fragment;
-            public string   AbsoluteUri;
-            public int      Hash;
-            public string   RemoteUrl;
-        };
-
-        private bool IsImplicitFile {
-            get {return (m_Flags & Flags.ImplicitFile) != 0;}
-        }
-
-        private bool IsUncOrDosPath {
-#if !PLATFORM_UNIX
-            get {return (m_Flags & (Flags.UncPath|Flags.DosPath)) != 0;}
-#else
-            get {return false;}
-#endif // !PLATFORM_UNIX
-        }
-
-        private bool IsDosPath {
-#if !PLATFORM_UNIX
-            get {return (m_Flags & Flags.DosPath) != 0;}
-#else
-            get {return false;}
-#endif // !PLATFORM_UNIX
-        }
-
-        private bool IsUncPath {
-#if !PLATFORM_UNIX
-            get {return (m_Flags & Flags.UncPath) != 0;}
-#else
-            get {return false;}
-#endif // !PLATFORM_UNIX
-        }
-
-        private Flags HostType {
-            get {return m_Flags & Flags.HostTypeMask;}
-        }
-
-        private UriParser Syntax {
-            get {
-                return m_Syntax;
-            }
-        }
-
-        private bool IsNotAbsoluteUri {
-            get {return (object) m_Syntax == null;}
-        }
-
-        //
-        // Checks if Iri parsing is allowed by the syntax & by config
-        //
-        private bool m_iriParsing;
-
-        //
-        // Statically checks if Iri parsing is allowed by the syntax & by config
-        //
-        internal static bool IriParsingStatic( UriParser syntax )
-        {
-            return (s_IriParsing && (((syntax != null) && syntax.InFact(UriSyntaxFlags.AllowIriParsing)) ||
-                   (syntax == null)));
-        }
-
-        //
-        // Checks if Idn is allowed by the syntax & by config
-        //
-        private bool AllowIdn
-        {
-            get { return    ((m_Syntax != null) && ((m_Syntax.Flags & UriSyntaxFlags.AllowIdn) != 0) &&
-                            ((s_IdnScope == UriIdnScope.All) || ((s_IdnScope == UriIdnScope.AllExceptIntranet)
-                                                                                && NotAny(Flags.IntranetUri)))); }
-        }
-
-        //
-        // Checks statically if Idn is allowed by the syntax & by config
-        //
-        private bool AllowIdnStatic(UriParser syntax, Flags flags)
-        {
-            return ((syntax != null) && ((syntax.Flags & UriSyntaxFlags.AllowIdn) != 0) &&
-                   ((s_IdnScope == UriIdnScope.All) || ((s_IdnScope == UriIdnScope.AllExceptIntranet)
-                                                                            && StaticNotAny(flags, Flags.IntranetUri))));
-        }
-
-        //
-        // check if the scheme + host are in intranet or not
-        // Used to determine of we apply idn or not
-        //
-        private static volatile IInternetSecurityManager s_ManagerRef = null;
-        private static object s_IntranetLock = new object();
-
-        private bool IsIntranet(string schemeHost)
-        {
-            bool error = false;
-            int zone = -1;
-            int E_FAIL = unchecked((int)0x80004005);
-
-            // MapUrlToZone call below fails on scheme length > 32 so we consider this
-            // not be be intranet
-            //
-            if (m_Syntax.SchemeName.Length > 32)
-                return false;
-
-            if (s_ManagerRef == null){
-                lock (s_IntranetLock){
-                    if(s_ManagerRef == null)
-                    {
-#if !FEATURE_PAL
-                        // Go through CoCreateInstance as creating arbitary COM object is no longer supported in AppX scenario
-                        Guid clsid = typeof(InternetSecurityManager).GUID;
-                        Guid iid = typeof(IInternetSecurityManager).GUID;
-
-                        object managerRef;
-                        UnsafeNclNativeMethods.CoCreateInstance(
-                            ref clsid ,
-                            IntPtr.Zero,
-                            UnsafeNclNativeMethods.CLSCTX_SERVER,
-                            ref iid,
-                            out managerRef
-                            );
-                        s_ManagerRef = managerRef as IInternetSecurityManager;
-#else
-                        s_ManagerRef = (IInternetSecurityManager)new InternetSecurityManager();
-#endif // !FEATURE_PAL                        
-                    }
-                }
-            }
-
-            try{
-                s_ManagerRef.MapUrlToZone(schemeHost.TrimStart(_WSchars), out zone, 0);
-            }
-            catch (COMException ex){
-                if (ex.ErrorCode == E_FAIL){    // E_FAIL
-                    error = true;
-                }
-            }
-            // If s_ManagerRef was initilized on an STA thread then it cannot be accessed from other threads.
-            // Visual Studio Unit Tests are the primary scenario for this.
-            catch (InvalidComObjectException) {
-                error = true;
-            }
-
-            if(zone == (int) SecurityZone.Intranet)
-                return true;
-
-            // Do dot check for intranet if zone is trusted or untrusted
-            // since an intranet zone may be in these zones as well
-            if ((zone == (int)SecurityZone.Trusted) ||
-                (zone == (int)SecurityZone.Untrusted) || error)
-            {
-                // do dot check
-                for (int i = 0; i < schemeHost.Length; ++i)
-                {
-                    if (schemeHost[i] == '.')
-                        return false;
-                }
-                return true;
-            }
-            return false;
-        }
-
-        internal bool UserDrivenParsing
-        {
-            get {
-                return (m_Flags & Flags.UserDrivenParsing) != 0;
-            }
-        }
-        private void SetUserDrivenParsing()
-        {
-            // we use = here to clear all parsing flags for a uri that we think is invalid.
-            m_Flags = Flags.UserDrivenParsing | (m_Flags & Flags.UserEscaped);
-        }
-
-        private ushort SecuredPathIndex {
-            get {
-                // This is one more trouble with a Dos Path.
-                // This property gets "safe" first path slash that is not the first if path = c:\
-                if (IsDosPath) {
-                    char ch = m_String[m_Info.Offset.Path];
-                    return (ushort)((ch == '/' || ch == '\\')? 3 :2);
-                }
-                return (ushort)0;
-            }
-        }
-
-        private bool NotAny(Flags flags) {
-            return (m_Flags & flags) == 0;
-        }
-
-        private bool InFact(Flags flags) {
-            return (m_Flags & flags) != 0;
-        }
-
-        private static bool StaticNotAny(Flags allFlags, Flags checkFlags) {
-            return (allFlags & checkFlags) == 0;
-        }
-
-        private static bool StaticInFact(Flags allFlags, Flags checkFlags) {
-            return (allFlags & checkFlags) != 0;
-        }
-
-        //
-        //
-        private UriInfo EnsureUriInfo() {
-            Flags cF = m_Flags;
-            if ((m_Flags & Flags.MinimalUriInfoSet) == 0) {
-                CreateUriInfo(cF);
-            }
-            return m_Info;
-        }
-        //
-        //
-        private void EnsureParseRemaining() {
-            if ((m_Flags & Flags.AllUriInfoSet) == 0) {
-                ParseRemaining();
-            }
-        }
-        //
-        //
-        private void EnsureHostString(bool allowDnsOptimization) {
-            EnsureUriInfo();
-            if ((object)m_Info.Host == null) {
-                if (allowDnsOptimization && InFact(Flags.CanonicalDnsHost)) {
-                    /* Optimization for a canonical DNS name
-                    *  ATTN: the host string won't be created,
-                    *  Hence ALL m_Info.Host callers first call EnsureHostString(false)
-                    *  For example IsLoopBack property is one of such callers.
-                    */
-                    return;
-                }
-                CreateHostString();
-            }
-        }
-
-        //
-        // Uri(string)
-        //
-        //  We expect to create a Uri from a display name - e.g. that was typed by
-        //  a user, or that was copied & pasted from a document. That is, we do not
-        //  expect already encoded URI to be supplied.
-        //
-        public Uri(string uriString){
-            if ((object)uriString == null)
-                throw new ArgumentNullException("uriString");
-
-            CreateThis(uriString, false, UriKind.Absolute);
-        }
-
-
-        //
-        // Uri(string, bool)
-        //
-        //  Uri constructor. Assumes that input string is canonically escaped
-        //
-        [Obsolete("The constructor has been deprecated. Please use new Uri(string). The dontEscape parameter is deprecated and is always false. http://go.microsoft.com/fwlink/?linkid=14202")]
-        public Uri(string uriString, bool dontEscape) {
-            if ((object)uriString == null)
-                throw new ArgumentNullException("uriString");
-
-            CreateThis(uriString, dontEscape, UriKind.Absolute);
-        }
-
-        //
-        // Uri(Uri, string, bool)
-        //
-        //  Uri combinatorial constructor. Do not perform character escaping if
-        //  DontEscape is true
-        //
-        [Obsolete("The constructor has been deprecated. Please new Uri(Uri, string). The dontEscape parameter is deprecated and is always false. http://go.microsoft.com/fwlink/?linkid=14202")]
-        public Uri(Uri baseUri, string relativeUri, bool dontEscape){
-            if ((object)baseUri == null)
-                throw new ArgumentNullException("baseUri");
-
-            if (!baseUri.IsAbsoluteUri)
-                throw new ArgumentOutOfRangeException("baseUri");
-
-            CreateUri(baseUri, relativeUri, dontEscape);
-        }
-
-        //
-        // Uri(string, UriKind);
-        //
-        public Uri(string uriString, UriKind uriKind)
-        {
-            if ((object)uriString == null)
-                throw new ArgumentNullException("uriString");
-
-            CreateThis(uriString, false, uriKind);
-        }
-
-
-        //
-        // Uri(Uri, string)
-        //
-        //  Construct a new Uri from a base and relative URI. The relative URI may
-        //  also be an absolute URI, in which case the resultant URI is constructed
-        //  entirely from it
-        //
-        public Uri(Uri baseUri, string relativeUri){
-            if ((object)baseUri == null)
-                throw new ArgumentNullException("baseUri");
-
-            if (!baseUri.IsAbsoluteUri)
-                throw new ArgumentOutOfRangeException("baseUri");
-
-            CreateUri(baseUri, relativeUri, false);
-        }
-
-        private void CreateUri(Uri baseUri, string relativeUri, bool dontEscape)
-        {
-            // Parse relativeUri and populate Uri internal data.
-            CreateThis(relativeUri, dontEscape, UriKind.RelativeOrAbsolute);
-
-            UriFormatException e;
-            if (baseUri.Syntax.IsSimple)
-            {
-                // Resolve Uris if possible OR get merged Uri String to re-parse below
-                Uri uriResult = ResolveHelper(baseUri, this, ref relativeUri, ref dontEscape, out e);
-
-                if (e != null)
-                    throw e;
-
-                // If resolved into a Uri then we build from that Uri
-                if (uriResult != null)
-                {
-                    if ((object)uriResult != (object)this)
-                        CreateThisFromUri(uriResult);
-
-                    return;
-                }
-            }
-            else
-            {
-                dontEscape = false;
-                relativeUri = baseUri.Syntax.InternalResolve(baseUri, this, out e);
-                if (e != null)
-                    throw e;
-            }
-
-            m_Flags = Flags.Zero;
-            m_Info = null;
-            m_Syntax = null;
-            // If not resolved, we reparse modified Uri string and populate Uri internal data.
-            CreateThis(relativeUri, dontEscape, UriKind.Absolute);
-        }
-
-        //
-        // Uri(Uri , Uri )
-        // Note: a static Create() method should be used by users, not this .ctor
-        //
-        public Uri(Uri baseUri, Uri relativeUri)
-        {
-            if ((object)baseUri == null)
-                throw new ArgumentNullException("baseUri");
-
-            if (!baseUri.IsAbsoluteUri)
-                throw new ArgumentOutOfRangeException("baseUri");
-
-            CreateThisFromUri(relativeUri);
-
-            string newUriString = null;
-            UriFormatException e;
-            bool dontEscape;
-
-            if (baseUri.Syntax.IsSimple)
-            {
-                dontEscape = InFact(Flags.UserEscaped);
-                relativeUri = ResolveHelper(baseUri, this, ref newUriString, ref dontEscape, out e);
-
-                if (e != null)
-                    throw e;
-
-                if (relativeUri != null)
-                {
-                    if ((object)relativeUri != (object)this)
-                        CreateThisFromUri(relativeUri);
-
-                    return;
-                }
-            }
-            else
-            {
-                dontEscape = false;
-                newUriString = baseUri.Syntax.InternalResolve(baseUri, this, out e);
-                if (e != null)
-                    throw e;
-            }
-
-            m_Flags = Flags.Zero;
-            m_Info = null;
-            m_Syntax = null;
-            CreateThis(newUriString, dontEscape, UriKind.Absolute);
-        }
-
-        //
-        // This method is shared by base+relative Uris constructors and is only called from them.
-        // The assumptions:
-        //  - baseUri is a valid absolute Uri
-        //  - relative part is not null and not empty
-        private unsafe static ParsingError GetCombinedString(Uri baseUri, string relativeStr, 
-            bool dontEscape, ref string result)
-        {
-            // NB: This is not RFC2396 compliant although it is inline with w3c.org recommendations
-            // This parser will allow the relativeStr to be an absolute Uri with the different scheme
-            // In fact this is strict violation of RFC2396
-            //
-            for (int i=0; i < relativeStr.Length; ++i)
-            {
-                if (relativeStr[i] == '/' || relativeStr[i] == '\\' || relativeStr[i] == '?' || relativeStr[i] == '#')
-                {
-                    break;
-                }
-                else if (relativeStr[i] == ':')
-                {
-                    if (i < 2)
-                    {
-                        // Note we don't support one-letter Uri schemes.
-                        // Hence anything like x:sdsd is a relative path and be added to the baseUri Path
-                        break;
-                    }
-                    string scheme =  relativeStr.Substring(0, i);
-                    fixed (char* sptr = scheme) {
-                        UriParser syntax = null;
-                        if (CheckSchemeSyntax(sptr, (ushort) scheme.Length, ref syntax) == ParsingError.None) {
-                            if (baseUri.Syntax == syntax) {
-                                //Remove the scheme for backward Uri parsers compatibility
-                                if (i+1 < relativeStr.Length) {
-                                    relativeStr = relativeStr.Substring(i+1);
-                                }
-                                else {
-                                    relativeStr = string.Empty;
-                                }
-                            }
-                            else {
-                                // This is the place where we switch the scheme.
-                                // Return relative part as the result Uri.
-                                result = relativeStr;
-                                return ParsingError.None;
-                            }
-                        }
-                    }
-                    break;
-                }
-            }
-
-            if (relativeStr.Length == 0) {
-                result = baseUri.OriginalString;
-                return ParsingError.None;
-            }
-
-            result = CombineUri(baseUri, relativeStr, dontEscape? UriFormat.UriEscaped: UriFormat.SafeUnescaped);
-            return ParsingError.None;
-        }
-        //
-        private static UriFormatException GetException(ParsingError err)
-        {
-            switch (err)
-            {
-                case ParsingError.None:
-                    return null;
-                // Could be OK for Relative Uri
-                case ParsingError.BadFormat:
-                    return new UriFormatException(SR.GetString(SR.net_uri_BadFormat));
-                case ParsingError.BadScheme:
-                    return new UriFormatException(SR.GetString(SR.net_uri_BadScheme));
-                case ParsingError.BadAuthority:
-                    return new UriFormatException(SR.GetString(SR.net_uri_BadAuthority));
-                case ParsingError.EmptyUriString:
-                    return new UriFormatException(SR.GetString(SR.net_uri_EmptyUri));
-                // Fatal
-                case ParsingError.SchemeLimit:
-                    return new UriFormatException(SR.GetString(SR.net_uri_SchemeLimit));
-                case ParsingError.SizeLimit:
-                    return new UriFormatException(SR.GetString(SR.net_uri_SizeLimit));
-                case ParsingError.MustRootedPath:
-                    return new UriFormatException(SR.GetString(SR.net_uri_MustRootedPath));
-                // Derived class controllable
-                case ParsingError.BadHostName:
-                    return new UriFormatException(SR.GetString(SR.net_uri_BadHostName));
-                case ParsingError.NonEmptyHost: //unix-only
-                    return new UriFormatException(SR.GetString(SR.net_uri_BadFormat));
-                case ParsingError.BadPort:
-                    return new UriFormatException(SR.GetString(SR.net_uri_BadPort));
-                case ParsingError.BadAuthorityTerminator:
-                    return new UriFormatException(SR.GetString(SR.net_uri_BadAuthorityTerminator));
-                case ParsingError.CannotCreateRelative:
-                    return new UriFormatException(SR.GetString(SR.net_uri_CannotCreateRelative));
-                default:
-                    break;
-            }
-            return new UriFormatException(SR.GetString(SR.net_uri_BadFormat));
-        }
-
-        #region !Silverlight
-
-        //
-        // ISerializable constructor
-        //
-        protected Uri(SerializationInfo serializationInfo, StreamingContext streamingContext)
-        {
-            string uriString = serializationInfo.GetString("AbsoluteUri");
-
-            if (uriString.Length != 0)
-            {
-                CreateThis(uriString, false, UriKind.Absolute);
-                return;
-            }
-
-            uriString = serializationInfo.GetString("RelativeUri");
-            if ((object)uriString == null)
-                throw new ArgumentNullException("uriString");
-
-            CreateThis(uriString, false, UriKind.Relative);
-        }
-
-        //
-        // ISerializable method
-        //
-        /// <internalonly/>
-        [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
-        [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter=true)]
-        void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
-        {
-            GetObjectData(serializationInfo, streamingContext);
-        }
-
-        //
-        // FxCop: provide some way for derived classes to access GetObjectData even if the derived class
-        // explicitly re-inherits ISerializable.
-        //
-        [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter=true)]
-        protected void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
-        {
-
-            if (IsAbsoluteUri)
-                serializationInfo.AddValue("AbsoluteUri", GetParts(UriComponents.SerializationInfoString, UriFormat.UriEscaped));
-            else
-            {
-                serializationInfo.AddValue("AbsoluteUri", string.Empty);
-                serializationInfo.AddValue("RelativeUri", GetParts(UriComponents.SerializationInfoString, UriFormat.UriEscaped));
-            }
-        }
-
-        #endregion !Silverlight
-
-        //
-        //
-        //
-        public string AbsolutePath {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                string path = PrivateAbsolutePath;
-                //
-                // 
-
-
-                if (IsDosPath && path[0] == '/') {
-                    path =  path.Substring(1);
-                }
-                return path;
-            }
-        }
-        //
-        private string PrivateAbsolutePath {
-            get {
-                UriInfo info = EnsureUriInfo();
-                if ((object) info.MoreInfo == null) {
-                    info.MoreInfo = new MoreInfo();
-                }
-                string result = info.MoreInfo.Path;
-                if ((object) result == null) {
-                    result = GetParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
-                    info.MoreInfo.Path = result;
-                }
-                return result;
-            }
-        }
-
-        //
-        //
-        //
-        public string AbsoluteUri {
-            get {
-                if (m_Syntax == null){
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                UriInfo info = EnsureUriInfo();
-                if ((object) info.MoreInfo == null) {
-                    info.MoreInfo = new MoreInfo();
-                }
-                string result = info.MoreInfo.AbsoluteUri;
-                if ((object) result == null) {
-                    result = GetParts(UriComponents.AbsoluteUri, UriFormat.UriEscaped);
-                    info.MoreInfo.AbsoluteUri = result;
-                }
-                return result;
-            }
-        }
-
-        //
-        // LocalPath
-        //
-        //  Returns a 'local' version of the path. This is mainly for file: URI
-        //  such that DOS and UNC paths are returned with '/' converted back to
-        //  '\', and any escape sequences converted
-        //
-        //  The form of the returned path is in NOT Escaped
-        //
-        public string LocalPath {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-                return GetLocalPath();
-            }
-        }
-
-        #region !Silverlight
-        //
-        //
-        // The result is of the form "hostname[:port]" Port is omitted if default
-        //
-        public string Authority {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                // 
-                return GetParts(UriComponents.Host | UriComponents.Port, UriFormat.UriEscaped);
-            }
-        }
-        //
-        //
-        public UriHostNameType HostNameType {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                if (m_Syntax.IsSimple)
-                    EnsureUriInfo();
-                else
-                {
-                    // For a custom parser we request HostString creation to confirm HostType
-                    EnsureHostString(false);
-                }
-
-                switch (HostType) {
-                    case Flags.DnsHostType:   return UriHostNameType.Dns;
-                    case Flags.IPv4HostType:  return UriHostNameType.IPv4;
-                    case Flags.IPv6HostType:  return UriHostNameType.IPv6;
-                    case Flags.BasicHostType: return UriHostNameType.Basic;
-#if !PLATFORM_UNIX
-                    case Flags.UncHostType:   return UriHostNameType.Basic; //return (UriHostNameType)(UriHostNameType.Basic+10);
-#endif // !PLATFORM_UNIX
-                    case Flags.UnknownHostType: return UriHostNameType.Unknown;
-                    default:
-                        break;
-                }
-                return UriHostNameType.Unknown;
-            }
-        }
-        //
-        //
-        public bool IsDefaultPort {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-                if (m_Syntax.IsSimple)
-                    EnsureUriInfo();
-                else
-                {
-                    // For a custom parser we request HostString creation that will aso set the port
-                    EnsureHostString(false);
-                }
-
-                return NotAny(Flags.NotDefaultPort);
-            }
-        }
-        //
-        //
-        public bool IsFile {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                return (object)m_Syntax.SchemeName == (object)UriSchemeFile;
-            }
-        }
-        //
-        //
-        public bool IsLoopback {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                EnsureHostString(false);
-
-                return InFact(Flags.LoopbackHost);
-            }
-        }
-
-        //
-        //
-        //  Gets the escaped Uri.AbsolutePath and Uri.Query
-        //  properties separated by a "?" character.
-        public string PathAndQuery {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                string result = GetParts(UriComponents.PathAndQuery, UriFormat.UriEscaped);
-                //
-                // 
-
-
-                if (IsDosPath && result[0] == '/') {
-                    result = result.Substring(1);
-                }
-                return result;
-            }
-        }
-
-        //
-        //
-        //  Gets an array of the segments that make up a URI.
-        public string[] Segments {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                string[] segments = null; // used to be a class cached result
-                if (segments == null) {
-
-                    string path = PrivateAbsolutePath;
-
-                    if (path.Length == 0) {
-                        segments = new string[0];
-                    }
-                    else {
-                        System.Collections.ArrayList pathSegments = new System.Collections.ArrayList();
-                        int current = 0;
-                        while (current < path.Length) {
-                            int next = path.IndexOf('/', current);
-                            if (next == -1) {
-                                next = path.Length - 1;
-                            }
-                            pathSegments.Add(path.Substring(current, (next - current) + 1));
-                            current = next + 1;
-                        }
-                        segments = (string[])(pathSegments.ToArray(typeof(string)));
-                    }
-                }
-                return segments;
-            }
-        }
-
-        #endregion !Silverlight
-
-        //
-        //
-        public bool IsUnc {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-                return IsUncPath;
-            }
-        }
-        
-        //
-        // Gets a hostname part (special formatting for IPv6 form)
-        public string Host {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                return GetParts(UriComponents.Host, UriFormat.UriEscaped);
-            }
-        }
-        
-        private static bool StaticIsFile(UriParser syntax)
-        {
-            return syntax.InFact(UriSyntaxFlags.FileLikeUri);
-        }
-
-        private static volatile bool s_ConfigInitialized; // Have the config values been initalized from config file
-        private static volatile bool s_ConfigInitializing; // used for recursion detection while init. config values
-
-        // Value from config Uri section
-        // The use of this IDN mechanic is discouraged on Win8+ due to native platform improvements.
-        private static volatile UriIdnScope s_IdnScope = IdnElement.EnabledDefaultValue;
-
-        // Value from config Uri section
-        // On by default in .NET 4.5+ and cannot be disabled by config.
-        private static volatile bool s_IriParsing = 
-            (UriParser.ShouldUseLegacyV2Quirks ? IriParsingElement.EnabledDefaultValue : true);
-
-        private static object s_initLock;
-
-        private static object InitializeLock {
-            get {
-                if (s_initLock == null) {
-                    object o = new object();
-                    Interlocked.CompareExchange(ref s_initLock, o, null);
-                }
-                return s_initLock;
-            }
-        }
-
-        //
-        // Reads values from config uri section
-        //
-        // This method is called if:
-        // - a Uri is constructed, we parse the string and we find '%', >127 chars, or 'xn--'
-        // - we parse the host and figure out if it is an IPv6 address
-        private static void InitializeUriConfig()
-        {
-            if (!s_ConfigInitialized) {
-                lock(InitializeLock) {
-                    if (!s_ConfigInitialized && !s_ConfigInitializing) {
-
-                        // setting s_ConfigInitializing to true makes sure, that in web scenarios,
-                        // where Uri instances may be created while parsing the web.config files, will not
-                        // call into this code block again. We'll enter the following code only once per
-                        // AppDomain.
-                        s_ConfigInitializing = true;
-                        UriSectionInternal section = UriSectionInternal.GetSection();
-
-                        if (section != null) {
-                            s_IdnScope = section.IdnScope;
-                            // Iri can no longer be altered by the config, it is always on.
-                            if (UriParser.ShouldUseLegacyV2Quirks) {
-                                s_IriParsing = section.IriParsing;
-                            }
-
-                            SetEscapedDotSlashSettings(section, "http");
-                            SetEscapedDotSlashSettings(section, "https");
-                            SetEscapedDotSlashSettings(section, Uri.UriSchemeWs);
-                            SetEscapedDotSlashSettings(section, Uri.UriSchemeWss);
-                        }
-
-                        s_ConfigInitialized = true;
-                        s_ConfigInitializing = false;
-                    }
-                }
-            }
-        }
-
-        // Legacy - This no longer has any affect in .NET 4.5 (non-quirks). See UriParser.HttpSyntaxFlags.
-        private static void SetEscapedDotSlashSettings(UriSectionInternal uriSection, string scheme)
-        {
-            // Currently we only support setting DontUnescapePathDotsAndSlashes for HTTP and HTTPS schemes.
-            // We ignore all other values. We won't throw for two reasons:
-            // - backward compatibility: Uri didn't throw so far.
-            // - the config section gets only read if we actually find e.g. a %-character in the Uri. If not, this
-            //   code never gets executed, resulting in a weird behavior for the customer: If one application run
-            //   doesn't use Uris with %-characters, it doesn't throw, if another run uses %-characters it throws.
-            //   => If we want to throw we have to rethink the current implementation.
-            SchemeSettingInternal schemeSetting = uriSection.GetSchemeSetting(scheme);
-            if (schemeSetting != null) {
-                // We check for equality, not if Options contains DontUnescapePathDotsAndSlashes:
-                // Currently we only support this flag. If more than this flag are set, then it is an invalid
-                // setting and we ignore it.
-                if (schemeSetting.Options == GenericUriParserOptions.DontUnescapePathDotsAndSlashes) {
-                    UriParser parser = UriParser.GetSyntax(scheme);
-                    parser.SetUpdatableFlags(UriSyntaxFlags.None);
-                }
-            }
-        }
-
-        private string GetLocalPath(){
-            EnsureParseRemaining();
-
-            //Other cases will get a Unix-style path
-            if (IsUncOrDosPath)
-            {
-                EnsureHostString(false);
-                int start;
-
-                // Do we have a valid local path right in m_string?
-                if (NotAny(Flags.HostNotCanonical|Flags.PathNotCanonical|Flags.ShouldBeCompressed)) {
-
-                    start = IsUncPath? m_Info.Offset.Host-2 :m_Info.Offset.Path;
-
-                    string str = (IsImplicitFile && m_Info.Offset.Host == (IsDosPath ? 0 : 2) && 
-                        m_Info.Offset.Query == m_Info.Offset.End)
-                            ? m_String
-                            : (IsDosPath && (m_String[start] == '/' || m_String[start] == '\\'))
-                                ? m_String.Substring(start + 1, m_Info.Offset.Query - start - 1)
-                                : m_String.Substring(start, m_Info.Offset.Query - start);
-
-                    // Should be a rare case, convert c|\ into c:\
-                    if (IsDosPath && str[1] == '|') {
-                        // Sadly, today there is no method for replacong just one occurrence
-                        str = str.Remove(1, 1);
-                        str = str.Insert(1, ":");
-                    }
-
-                    // check for all back slashes (though may be string.Replace is smart?)
-                    for (int i = 0; i < str.Length; ++i) {
-                        if (str[i] == '/') {
-                            str = str.Replace('/', '\\');
-                            break;
-                        }
-                    }
-
-                    return str;
-                }
-
-                // Not everything went well, trying harder
-
-                char[] result;
-                int count = 0;
-                start = m_Info.Offset.Path;
-
-                string host = m_Info.Host;
-                result = new char [host.Length + 3 + m_Info.Offset.Fragment - m_Info.Offset.Path ];
-
-                if (IsUncPath)
-                {
-                    result[0] = '\\';
-                    result[1] = '\\';
-                    count = 2;
-
-                    UriHelper.UnescapeString(host, 0, host.Length, result, ref count, c_DummyChar, c_DummyChar, 
-                        c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, false);
-
-                }
-                else {
-                    // Dos path
-                    if(m_String[start] == '/' ||  m_String[start] == '\\') {
-                        // Skip leading slash for a DOS path
-                        ++start;
-                    }
-                }
-
-
-                ushort pathStart = (ushort)count; //save for optional Compress() call
-
-                UnescapeMode mode = (InFact(Flags.PathNotCanonical) && !IsImplicitFile) 
-                    ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll): UnescapeMode.CopyOnly;
-                UriHelper.UnescapeString(m_String, start, m_Info.Offset.Query, result, ref count, c_DummyChar, 
-                    c_DummyChar, c_DummyChar, mode, m_Syntax, true);
-
-                // Possibly convert c|\ into c:\
-                if (result[1] == '|')
-                    result[1] = ':';
-
-                if (InFact(Flags.ShouldBeCompressed)) {
-                    // suspecting not compressed path
-                    // For a dos path we won't compress the "x:" part if found /../ sequences
-                    result = Compress(result, (ushort)(IsDosPath? pathStart + 2: pathStart), ref count, m_Syntax);
-                }
-
-                // We don't know whether all slashes were the back ones
-                // Plus going through Compress will turn them into / anyway
-                // Converting / back into \
-                for (ushort i = 0; i < (ushort) count; ++i) {
-                    if (result[i] == '/') {
-                        result[i] = '\\';
-                    }
-                }
-
-                return new string(result, 0, count);
-
-            }
-            else {
-                // Return unescaped canonical path
-                // Note we cannot call GetParts here because it has circular dependancy on GelLocalPath method
-                return GetUnescapedParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.Unescaped);
-            }
-        }
-
-        //
-        //
-        //
-        //
-        public int Port {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                if (m_Syntax.IsSimple)
-                    EnsureUriInfo();
-                else
-                {
-                    // For a custom parser we request HostString creation that will aso set the port
-                    EnsureHostString(false);
-                }
-
-                if (InFact(Flags.NotDefaultPort)) {
-                    return (int)m_Info.Offset.PortValue;
-                }
-                return m_Syntax.DefaultPort;
-            }
-        }
-        //
-        //
-        //
-        //  Gets the escaped query.
-        public string Query {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                UriInfo info = EnsureUriInfo();
-                if ((object)info.MoreInfo == null) {
-                    info.MoreInfo = new MoreInfo();
-                }
-                string result = info.MoreInfo.Query;
-                if ((object)result == null) {
-                    result = GetParts(UriComponents.Query | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
-                    info.MoreInfo.Query = result;
-                }
-                return result;
-            }
-        }
-        //
-        //
-        //
-        //    Gets the escaped fragment.
-        public string Fragment {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                UriInfo info = EnsureUriInfo();
-                if ((object)info.MoreInfo == null) {
-                    info.MoreInfo = new MoreInfo();
-                }
-                string result = info.MoreInfo.Fragment;
-                if ((object)result == null) {
-                    result = GetParts(UriComponents.Fragment | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
-                    info.MoreInfo.Fragment = result;
-                }
-                return result;
-            }
-        }
-
-        //
-        //  Gets the Scheme string of this Uri
-        //
-        //
-        public string Scheme {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                return m_Syntax.SchemeName;
-            }
-        }
-
-        //
-        //  Was the original string switched from m_String to m_OriginalUnicodeString
-        //  Will happen when Iri is turned on and we have unicode chars or of idn is
-        //  is on and we have an idn or unicode host.
-        //
-        private bool OriginalStringSwitched
-        {
-            get{return ((m_iriParsing && InFact(Flags.HasUnicode)) ||
-                        (AllowIdn && (InFact(Flags.IdnHost) || InFact(Flags.UnicodeHost))));}
-        }
-        //
-        //    Gets the exact string passed by a user.
-        public String OriginalString {
-            get {
-                return OriginalStringSwitched ? m_originalUnicodeString : m_String;
-            }
-        }
-
-        //
-        //    Gets the host string that is unescaped and if it's Ipv6 host,
-        //    then the returned string is suitable for DNS lookup.
-        //
-        //    For Ipv6 this will strip [] and add ScopeId if was found in the original string
-        public string DnsSafeHost {
-            get {
-
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                if (AllowIdn && (((m_Flags & Flags.IdnHost) != 0) || ((m_Flags & Flags.UnicodeHost) != 0))){
-                    // return pre generated idn
-                    EnsureUriInfo();
-                    return m_Info.DnsSafeHost;
-                }
-
-                EnsureHostString(false);
-
-                if (!String.IsNullOrEmpty(m_Info.DnsSafeHost)) {
-                    // Cached
-                    return m_Info.DnsSafeHost;
-                } else if (m_Info.Host.Length == 0) {
-                    // Empty host, no possible processing
-                    return String.Empty;
-                }
-
-                // Special case, will include ScopeID and strip [] around IPv6
-                // This will also unescape the host string
-                string ret = m_Info.Host;
-
-                if (HostType == Flags.IPv6HostType) {
-                    ret = ret.Substring(1, ret.Length - 2);
-                    if ((object)m_Info.ScopeId != null) {
-                        ret += m_Info.ScopeId;
-                    }
-                }
-                // Validate that this basic host qualifies as Dns safe,
-                // It has looser parsing rules that might allow otherwise.
-                // It might be a registry-based host from RFC 2396 Section 3.2.1
-                else if (HostType == Flags.BasicHostType 
-                    && InFact(Flags.HostNotCanonical | Flags.E_HostNotCanonical)) {
-                    // Unescape everything
-                    char[] dest = new char[ret.Length];
-                    int count = 0;
-                    UriHelper.UnescapeString(ret, 0, ret.Length, dest, ref count, c_DummyChar, c_DummyChar, 
-                        c_DummyChar, UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, false);
-                    ret = new string(dest, 0, count);
-                }
-
-                m_Info.DnsSafeHost = ret;
-
-                return ret;
-            }
-        }
-
-        // Returns the host name represented as IDN (using punycode encoding) regardless of app.config settings
-        public string IdnHost {
-            get {
-                string host = this.DnsSafeHost;
-
-                if (HostType == Flags.DnsHostType) {
-                    host = DomainNameHelper.IdnEquivalent(host);
-                }
-
-                return host;
-            }
-        }
-
-        //
-        //  Returns false if the string passed in the constructor cannot be parsed as
-        //  valid AbsoluteUri. This could be a relative Uri instead.
-        //
-        public bool IsAbsoluteUri {
-            get {
-                return m_Syntax != null;
-            }
-        }
-        //
-        //
-        //  Returns 'true' if the 'dontEscape' parameter was set to 'true ' when the Uri instance was created.
-        public bool UserEscaped {
-            get {
-                return InFact(Flags.UserEscaped);
-            }
-        }
-        //
-        //
-        //  Gets the user name, password, and other user specific information associated
-        //  with the Uniform Resource Identifier (URI).
-        public string UserInfo {
-            get {
-                if (IsNotAbsoluteUri) {
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-                }
-
-                return GetParts(UriComponents.UserInfo, UriFormat.UriEscaped);
-            }
-        }
-
-        #region !Silverlight
-
-        //
-        // CheckHostName
-        //
-        //  Determines whether a host name authority is a valid Host name according
-        //  to DNS naming rules and IPv4 canonicalization rules
-        //
-        // Returns:
-        //  true if <name> is valid else false
-        //
-        // Throws:
-        //  Nothing
-        //
-        public static UriHostNameType CheckHostName(string name) {
-
-            if ((object)name == null || name.Length == 0 || name.Length > short.MaxValue) {
-                return UriHostNameType.Unknown;
-            }
-            int end = name.Length;
-            unsafe {
-                fixed (char* fixedName = name) {
-
-                    if (name[0] == '[' && name[name.Length-1] == ']') {
-                        // we require that _entire_ name is recognized as ipv6 address
-                        if (IPv6AddressHelper.IsValid(fixedName, 1, ref end) && end == name.Length) {
-                            return UriHostNameType.IPv6;
-                        }
-                    }
-                    end = name.Length;
-                    if (IPv4AddressHelper.IsValid(fixedName, 0 , ref end, false, false, false) && end == name.Length) {
-                        return UriHostNameType.IPv4;
-                    }
-                    end = name.Length;
-                    bool dummyBool = false;
-                    if (DomainNameHelper.IsValid(fixedName, 0, ref end, ref dummyBool, false) && end == name.Length) {
-                        return UriHostNameType.Dns;
-                    }
-
-                    end = name.Length;
-                    dummyBool = false;
-                    if (DomainNameHelper.IsValidByIri(fixedName, 0, ref end, ref dummyBool, false) 
-                        && end == name.Length) {
-                        return UriHostNameType.Dns;
-                    }
-                }
-
-                //This checks the form without []
-                end = name.Length+2;
-                // we require that _entire_ name is recognized as ipv6 address
-                name = "["+name+"]";
-                fixed (char* newFixedName = name) {
-                    if (IPv6AddressHelper.IsValid(newFixedName, 1, ref end) && end == name.Length) {
-                        return UriHostNameType.IPv6;
-                    }
-                }
-            }
-            return UriHostNameType.Unknown;
-        }
-
-        //
-        // GetLeftPart
-        //
-        //  Returns part of the URI based on the parameters:
-        //
-        // Inputs:
-        //  <argument>  part
-        //      Which part of the URI to return
-        //
-        // Returns:
-        //  The requested substring
-        //
-        // Throws:
-        //  UriFormatException if URI type doesn't have host-port or authority parts
-        //
-        public string GetLeftPart(UriPartial part) {
-            if (IsNotAbsoluteUri) {
-                throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-            }
-
-            EnsureUriInfo();
-            const UriComponents NonPathPart = (UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port);
-
-            switch (part) {
-                case UriPartial.Scheme:
-
-                    return GetParts(UriComponents.Scheme | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
-
-                case UriPartial.Authority:
-
-                    if (NotAny(Flags.AuthorityFound) || IsDosPath) {
-
-                        // 
-
-
-
-                        // From V1.0 comments:
-
-                        // anything that didn't have "//" after the scheme name
-                        // (mailto: and news: e.g.) doesn't have an authority
-                        //
-
-                        return String.Empty;
-                    }
-                    return GetParts(NonPathPart, UriFormat.UriEscaped);
-
-                case UriPartial.Path:
-                    return GetParts(NonPathPart | UriComponents.Path, UriFormat.UriEscaped);
-
-                case UriPartial.Query:
-                    return GetParts(NonPathPart | UriComponents.Path | UriComponents.Query, UriFormat.UriEscaped);
-
-            }
-            throw new ArgumentException("part");
-        }
-
-        //
-        //
-        /// Transforms a character into its hexadecimal representation.
-        public static string HexEscape(char character) {
-            if (character > '\xff') {
-                throw new ArgumentOutOfRangeException("character");
-            }
-            char[] chars = new char[3];
-            int pos = 0;
-            UriHelper.EscapeAsciiChar(character, chars, ref pos);
-            return new string(chars);
-        }
-
-        //
-        // HexUnescape
-        //
-        //  Converts a substring of the form "%XX" to the single character represented
-        //  by the hexadecimal value XX. If the substring s[Index] does not conform to
-        //  the hex encoding format then the character at s[Index] is returned
-        //
-        // Inputs:
-        //  <argument>  pattern
-        //      String from which to read the hexadecimal encoded substring
-        //
-        //  <argument>  index
-        //      Offset within <pattern> from which to start reading the hexadecimal
-        //      encoded substring
-        //
-        // Outputs:
-        //  <argument>  index
-        //      Incremented to the next character position within the string. This
-        //      may be EOS if this was the last character/encoding within <pattern>
-        //
-        // Returns:
-        //  Either the converted character if <pattern>[<index>] was hex encoded, or
-        //  the character at <pattern>[<index>]
-        //
-        // Throws:
-        //  ArgumentOutOfRangeException
-        //
-
-        public static char HexUnescape(string pattern, ref int index) {
-            if ((index < 0) || (index >= pattern.Length)) {
-                throw new ArgumentOutOfRangeException("index");
-            }
-            if ((pattern[index] == '%')
-                && (pattern.Length - index >= 3)) {
-                char ret = UriHelper.EscapedAscii(pattern[index + 1], pattern[index + 2]);
-                if (ret != c_DummyChar) {
-                    index += 3;
-                    return ret;
-                }
-            }
-            return pattern[index++];
-        }
-
-        //
-        // IsHexEncoding
-        //
-        //  Determines whether a substring has the URI hex encoding format of '%'
-        //  followed by 2 hexadecimal characters
-        //
-        // Inputs:
-        //  <argument>  pattern
-        //      String to check
-        //
-        //  <argument>  index
-        //      Offset in <pattern> at which to check substring for hex encoding
-        //
-        // Assumes:
-        //  0 <= <index> < <pattern>.Length
-        //
-        // Returns:
-        //  true if <pattern>[<index>] is hex encoded, else false
-        //
-        // Throws:
-        //  Nothing
-        //
-        public static bool IsHexEncoding(string pattern, int index) {
-            if ((pattern.Length - index) < 3) {
-                return false;
-            }
-            if ((pattern[index] == '%') && UriHelper.EscapedAscii(pattern[index + 1], pattern[index + 2]) != c_DummyChar) {
-                return true;
-            }
-            return false;
-        }
-
-        //
-        // Is this a gen delim char from RFC 3986
-        //
-        internal static bool IsGenDelim(char ch)
-        {
-            return (ch == ':' || ch == '/' || ch == '?' || ch == '#' || ch == '[' || ch == ']' || ch == '@');
-        }
-
-        #endregion !Silverlight
-
-        //
-        // CheckSchemeName
-        //
-        //  Determines whether a string is a valid scheme name according to RFC 2396.
-        //  Syntax is:
-        //      scheme = alpha *(alpha | digit | '+' | '-' | '.')
-        //
-        public static bool CheckSchemeName(string schemeName) {
-            if (((object)schemeName == null)
-                || (schemeName.Length == 0)
-                || !IsAsciiLetter(schemeName[0])) {
-                return false;
-            }
-            for (int i = schemeName.Length - 1; i > 0; --i) {
-                if (!(IsAsciiLetterOrDigit(schemeName[i])
-                    || (schemeName[i] == '+')
-                    || (schemeName[i] == '-')
-                    || (schemeName[i] == '.'))) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        //
-        // IsHexDigit
-        //
-        //  Determines whether a character is a valid hexadecimal digit in the range
-        //  [0..9] | [A..F] | [a..f]
-        //
-        // Inputs:
-        //  <argument>  character
-        //      Character to test
-        //
-        // Returns:
-        //  true if <character> is a hexadecimal digit character
-        //
-        // Throws:
-        //  Nothing
-        //
-        public static bool IsHexDigit(char character) {
-            return ((character >= '0') && (character <= '9'))
-                || ((character >= 'A') && (character <= 'F'))
-                || ((character >= 'a') && (character <= 'f'));
-        }
-
-        //
-        // Returns:
-        //  Number in the range 0..15
-        //
-        // Throws:
-        //  ArgumentException
-        //
-        public static int FromHex(char digit) {
-            if (((digit >= '0') && (digit <= '9'))
-                || ((digit >= 'A') && (digit <= 'F'))
-                || ((digit >= 'a') && (digit <= 'f'))) {
-                return  (digit <= '9')
-                    ? ((int)digit - (int)'0')
-                    : (((digit <= 'F')
-                    ? ((int)digit - (int)'A')
-                    : ((int)digit - (int)'a'))
-                    + 10);
-            }
-            throw new ArgumentException("digit");
-        }
-        //
-        // GetHashCode
-        //
-        //  Overrides default function (in Object class)
-        //
-        //
-        [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
-        public override int GetHashCode() {
-            if (IsNotAbsoluteUri)
-            {
-                return CalculateCaseInsensitiveHashCode(OriginalString);
-            }
-
-            // Consider moving hash code storage from m_Info.MoreInfo to m_Info
-            UriInfo info = EnsureUriInfo();
-            if ((object)info.MoreInfo == null) {
-                info.MoreInfo = new MoreInfo();
-            }
-            int tempHash = info.MoreInfo.Hash;
-            if (tempHash == 0) {
-                string chkString = info.MoreInfo.RemoteUrl;
-                if ((object) chkString == null)
-                    chkString = GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped);
-                tempHash = CalculateCaseInsensitiveHashCode(chkString);
-                if (tempHash == 0) {
-                    tempHash = 0x1000000;   //making it not zero still large enough to be maped to zero by a hashtable
-                }
-                info.MoreInfo.Hash = tempHash;
-            }
-            return tempHash;
-        }
-
-        //
-        // ToString
-        //
-        // The better implementation would be just
-        //
-        private const UriFormat V1ToStringUnescape = (UriFormat)0x7FFF;
-
-        [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
-        public override string ToString()
-        {
-            if (m_Syntax == null) {
-                return (m_iriParsing && InFact(Flags.HasUnicode)) ? m_String : OriginalString;
-            }
-
-            EnsureUriInfo();
-            if ((object)m_Info.String == null)
-            {
-
-                // V1.1 compat unless #353711 is appoved, otheriwse it should be just a call into GetParts() as shown below
-                // m_Info.String = GetParts(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
-
-                if (Syntax.IsSimple)
-                    m_Info.String = GetComponentsHelper(UriComponents.AbsoluteUri, V1ToStringUnescape);
-                else
-                    m_Info.String = GetParts(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
-
-            }
-            return m_Info.String;
-        }
-
-        //
-        //
-        //  A static shortcut to Uri.Equals
-        //
-        [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
-        public static bool operator == (Uri uri1, Uri uri2) {
-            if ((object)uri1 == (object)uri2) {
-                return true;
-            }
-            if ((object)uri1 == null || (object)uri2 == null) {
-                return false;
-            }
-            return uri2.Equals(uri1);
-        }
-
-        //
-        //
-        //  A static shortcut to !Uri.Equals
-        //
-        [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
-        public static bool operator != (Uri uri1, Uri uri2) {
-            if ((object)uri1 == (object)uri2) {
-                return false;
-            }
-
-            if ((object)uri1 == null || (object)uri2 == null) {
-                return true;
-            }
-
-            return !uri2.Equals(uri1);
-        }
-
-
-
-        //
-        // Equals
-        //
-        //  Overrides default function (in Object class)
-        //
-        // Assumes:
-        //  <comparand> is an object of class Uri
-        //
-        // Returns:
-        //  true if objects have the same value, else false
-        //
-        // Throws:
-        //  Nothing
-        //
-        [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
-        public override bool Equals(object comparand) {
-            if ((object) comparand == null) {
-                return false;
-            }
-
-            if ((object)this == (object)comparand) {
-                return true;
-            }
-
-            Uri obj = comparand as Uri;
-
-            //
-            // we allow comparisons of Uri and String objects only. If a string
-            // is passed, convert to Uri. This is inefficient, but allows us to
-            // canonicalize the comparand, making comparison possible
-            //
-            if ((object)obj == null) {
-                string s = comparand as string;
-
-                if ((object)s == null)
-                    return false;
-
-                if (!TryCreate(s, UriKind.RelativeOrAbsolute, out obj))
-                    return false;
-            }
-
-            // Since v1.0 two Uris are equal if everything but fragment and UserInfo does match
-
-            // This check is for a case where we already fixed up the equal references
-            if ((object)this.m_String == (object)obj.m_String) {
-                return true;
-            }
-
-            if (IsAbsoluteUri != obj.IsAbsoluteUri)
-                return false;
-
-            if (IsNotAbsoluteUri)
-                return OriginalString.Equals(obj.OriginalString);
-
-            if (NotAny(Flags.AllUriInfoSet) || obj.NotAny(Flags.AllUriInfoSet)) {
-                // Try raw compare for m_Strings as the last chance to keep the working set small
-                if (!IsUncOrDosPath ) {
-                    if (m_String.Length == obj.m_String.Length) {
-                        unsafe {
-                            // Try case sensitive compare on m_Strings
-                            fixed (char* pMe = m_String) {
-                                fixed (char* pShe = obj.m_String) {
-                                    // This will never go negative since m_String is checked to be a valid URI
-                                    int i = (m_String.Length-1);
-                                    for ( ;i >= 0 ; --i) {
-                                        if (*(pMe+i) != *(pShe+i)) {
-                                            break;
-                                        }
-                                    }
-                                    if (i == -1) {
-                                        return true;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                else if (String.Compare(m_String, obj.m_String, StringComparison.OrdinalIgnoreCase) == 0) {
-                    return true;
-                }
-            }
-
-            // Note that equality test will bring the working set of both
-            // objects up to creation of m_Info.MoreInfo member
-            EnsureUriInfo();
-            obj.EnsureUriInfo();
-
-            if (!UserDrivenParsing && !obj.UserDrivenParsing && Syntax.IsSimple && obj.Syntax.IsSimple)
-            {
-                // Optimization of canonical DNS names by avoiding host string creation.
-                // Note there could be explicit ports specified that would invalidate path offsets
-                if (InFact(Flags.CanonicalDnsHost) && obj.InFact(Flags.CanonicalDnsHost)) {
-                    ushort i1 = m_Info.Offset.Host;
-                    ushort end1 = m_Info.Offset.Path;
-
-                    ushort i2 = obj.m_Info.Offset.Host;
-                    ushort end2 = obj.m_Info.Offset.Path;
-                    string str = obj.m_String;
-                    //Taking the shortest part
-                    if (end1-i1 > end2-i2) {
-                        end1 = (ushort)(i1 + end2-i2);
-                    }
-                    // compare and break on ':' if found
-                    while (i1 < end1) {
-                        if (m_String[i1] != str[i2]) {
-                            return false;
-                        }
-                        if (str[i2] == ':') {
-                            // The other must have ':' too to have equal host
-                            break;
-                        }
-                        ++i1;++i2;
-                    }
-
-                    // The longest host must have ':' or be of the same size
-                    if (i1 < m_Info.Offset.Path && m_String[i1] != ':') {
-                        return false;
-                    }
-                    if (i2 < end2 && str[i2] != ':') {
-                        return false;
-                    }
-                    //hosts are equal!
-                }
-                else {
-                    EnsureHostString(false);
-                    obj.EnsureHostString(false);
-                    if (!m_Info.Host.Equals(obj.m_Info.Host)) {
-                        return false;
-                    }
-                }
-
-                if (Port != obj.Port) {
-                    return false;
-                }
-            }
-
-            // see Whidbey#21590
-            // We want to cache RemoteUrl to improve perf for Uri as a key.
-            // We should consider reducing the overall working set by not caching some other properties mentioned in MoreInfo
-
-            // Mutli-threading!
-            UriInfo meInfo  = m_Info;
-            UriInfo sheInfo = obj.m_Info;
-            if ((object)meInfo.MoreInfo == null) {
-                meInfo.MoreInfo = new MoreInfo();
-            }
-            if ((object)sheInfo.MoreInfo == null) {
-                sheInfo.MoreInfo = new MoreInfo();
-            }
-
-            // NB: To avoid a race condition when creating MoreInfo field
-            // "meInfo" and "sheInfo" shall remain as local copies.
-            string me = meInfo.MoreInfo.RemoteUrl;
-            if ((object)me == null) {
-                me = GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped);
-                meInfo.MoreInfo.RemoteUrl = me;
-            }
-            string she = sheInfo.MoreInfo.RemoteUrl;
-            if ((object)she == null) {
-                she = obj.GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped);
-                sheInfo.MoreInfo.RemoteUrl = she;
-            }
-
-            if (!IsUncOrDosPath ) {
-                if (me.Length != she.Length) {
-                    return false;
-                }
-                unsafe {
-                    // Try case sensitive compare on m_Strings
-                    fixed (char* pMe = me) {
-                        fixed (char* pShe = she) {
-                            char *endMe  = pMe  + me.Length;
-                            char *endShe = pShe + me.Length;
-                            while (endMe != pMe) {
-                                if (*--endMe != *--endShe) {
-                                    return false;
-                                }
-                            }
-                            return true;
-                        }
-                    }
-                }
-            }
-
-
-            // if IsUncOrDosPath is true then we ignore case in the path comparison
-            // Get Unescaped form as most safe for the comparison
-            // Fragment AND UserInfo are ignored
-            //
-            return (String.Compare(meInfo.MoreInfo.RemoteUrl,
-                                   sheInfo.MoreInfo.RemoteUrl,
-                                   IsUncOrDosPath ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal ) == 0);
-        }
-        //
-        public Uri MakeRelativeUri(Uri uri)
-        {
-            if ((object)uri == null)
-                throw new ArgumentNullException("uri");
-
-            if (IsNotAbsoluteUri || uri.IsNotAbsoluteUri)
-                throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-
-            // Note that the UserInfo part is ignored when computing a relative Uri.
-            if ((Scheme == uri.Scheme) && (Host == uri.Host) && (Port == uri.Port))
-            {
-                String otherPath = uri.AbsolutePath;
-
-                // Relative Path
-                String relativeUriString = PathDifference(AbsolutePath, otherPath, !IsUncOrDosPath);
-
-                // Relative Uri's cannot have a colon ':' in the first path segment (RFC 3986, Section 4.2)
-                if (CheckForColonInFirstPathSegment(relativeUriString)
-                    // Except for full implicit dos file paths
-                    && !(uri.IsDosPath && otherPath.Equals(relativeUriString, StringComparison.Ordinal)))
-                    relativeUriString = "./" + relativeUriString;
-                
-                // Query & Fragment
-                relativeUriString += uri.GetParts(UriComponents.Query | UriComponents.Fragment, UriFormat.UriEscaped);
-
-                return new Uri(relativeUriString, UriKind.Relative);
-            }
-            return uri;
-        }
-
-        //
-        // http://www.ietf.org/rfc/rfc3986.txt
-        // 
-        // 3.3.  Path
-        // In addition, a URI reference (Section 4.1) may be a relative-path reference, in which case the  first 
-        // path segment cannot contain a colon (":") character.
-        // 
-        // 4.2.  Relative Reference
-        // A path segment that contains a colon character (e.g., "this:that") cannot be used as the first segment 
-        // of a relative-path reference, as it would be mistaken for a scheme name.  Such a segment must be   
-        // preceded by a dot-segment (e.g., "./this:that") to make a relative-path reference.
-        // 
-        // 5.4.2. Abnormal Examples 
-        // http:(relativeUri) may be considered a valid relative Uri.
-        // 
-        // Returns true if a colon is found in the first path segment, false otherwise
-        // 
-        private static bool CheckForColonInFirstPathSegment(String uriString)
-        {
-            // Check for anything that may terminate the first regular path segment
-            // or an illegal colon
-            char[] pathDelims = new char[] { ':', '\\', '/', '?', '#' };
-            int index = uriString.IndexOfAny(pathDelims);
-
-            return (index >= 0 && uriString[index] == ':');
-        }
-        // This is used by UriBuilder, 
-
-        internal unsafe static string InternalEscapeString(string rawString) {
-            if ((object)rawString == null)
-                return String.Empty;
-
-            int position = 0;
-            char[] dest = UriHelper.EscapeString(rawString, 0, rawString.Length, null, ref position, true, '?', '#', '%');
-            if ((object)dest == null)
-                return rawString;
-
-            return new string(dest, 0, position);
-        }
-
-        //
-        //  This method is called first to figure out the scheme or a simple file path
-        //  Is called only at the .ctor time
-        //
-        private static unsafe ParsingError ParseScheme(string uriString, ref Flags flags, ref UriParser syntax)
-        {
-            int length = uriString.Length;
-            if (length == 0)
-                return ParsingError.EmptyUriString;
-
-            // we don;t work with >= 64k Uris
-            if (length >= c_MaxUriBufferSize)
-                return ParsingError.SizeLimit;
-
-            //STEP1: parse scheme, lookup this Uri Syntax or create one using UnknownV1SyntaxFlags uri syntax template
-            fixed (char* pUriString = uriString)
-            {
-                ParsingError err = ParsingError.None;
-                ushort idx = ParseSchemeCheckImplicitFile(pUriString, (ushort)length, ref err, ref flags, ref syntax);
-
-                if (err != ParsingError.None)
-                    return err;
-
-                flags |= (Flags)idx;
-             }
-             return ParsingError.None;
-        }
-
-        //
-        // A wrapper for ParseMinimal() called from a user parser
-        // It signals back that the call has been done
-        // plus it communicates back a flag for an error if any
-        //
-        internal UriFormatException ParseMinimal()
-        {
-            ParsingError result = PrivateParseMinimal();
-            if (result == ParsingError.None)
-                return null;
-
-            // Means the we think the Uri is invalid, bu that can be later overriden by a user parser
-            m_Flags |= Flags.ErrorOrParsingRecursion;
-
-            return GetException(result);
-        }
-        //
-        //
-        //  This method tries to parse the minimal information needed to certify the valifity
-        //  of a uri string
-        //
-        //      scheme://userinfo@host:Port/Path?Query#Fragment
-        //
-        //  The method must be called only at the .ctor time
-        //
-        //  Returns ParsingError.None if the Uri syntax is valid, an error otheriwse
-        //
-        private unsafe ParsingError PrivateParseMinimal()
-        {
-            ushort idx = (ushort) (m_Flags & Flags.IndexMask);
-            ushort length = (ushort) m_String.Length;
-            string newHost = null;      // stores newly parsed host when original strings are being switched
-
-            // Means a custom UriParser did call "base" InitializeAndValidate()
-            m_Flags &= ~(Flags.IndexMask | Flags.UserDrivenParsing);
-
-            //STEP2: Parse up to the port
-
-            fixed (char* pUriString =   ((m_iriParsing &&
-                                        ((m_Flags & Flags.HasUnicode)!=0) &&
-                                        ((m_Flags & Flags.HostUnicodeNormalized) == 0)) ? m_originalUnicodeString : m_String))
-            {
-                // Cut trailing spaces in m_String
-                if (length > idx && IsLWS(pUriString[length-1]))
-                {
-                    --length;
-                    while (length != idx && IsLWS(pUriString[--length]))
-                        ;
-                    ++length;
-                }
-
-                // Microsoft codereview:
-                // Old Uri parser tries to figure out on a DosPath in all cases.
-                // Hence http://c:/ is treated as as DosPath without the host while it should be a host "c", port 80
-                //
-                // This block is compatible with Old Uri parser in terms it will look for the DosPath if the scheme
-                // syntax allows both empty hostnames and DosPath
-                //
-#if !PLATFORM_UNIX
-                if (m_Syntax.IsAllSet(UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowDOSPath) 
-                    && NotAny(Flags.ImplicitFile) && (idx + 1 < length)) {
-
-                    char c;
-                    ushort i = (ushort) idx;
-
-                    // V1 Compat: Allow _compression_ of > 3 slashes only for File scheme, see VsWhidbey 87448.
-                    // This will skip all slashes and if their number is 2+ it sets the AuthorityFound flag
-                    for (; i < length; ++i) {
-                        if (!((c=pUriString[i])== '\\' || c == '/'))
-                            break;
-                    }
-
-                    if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri) || i-idx <= 3) {
-                        // if more than one slash after the scheme, the authority is present
-                        if (i-idx >= 2) {
-                            m_Flags |= Flags.AuthorityFound;
-                        }
-                        // DOS-like path?
-                        if (i+1 < (ushort) length  && ((c=pUriString[i+1]) == ':' || c == '|') && 
-                            IsAsciiLetter(pUriString[i])) {
-
-                            if (i+2 >= (ushort) length || ((c=pUriString[i+2]) != '\\' && c != '/'))
-                            {
-                                // report an error but only for a file: scheme
-                                if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri))
-                                    return ParsingError.MustRootedPath;
-                            }
-                            else
-                            {
-                                // This will set IsDosPath
-                                m_Flags |= Flags.DosPath;
-
-                                if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority)) {
-                                    // when DosPath found and Authority is required, set this flag even if Authority is empty
-                                    m_Flags |= Flags.AuthorityFound;
-                                }
-                                if (i != idx && i-idx != 2) {
-                                    //This will remember that DosPath is rooted
-                                    idx = (ushort)(i-1);
-                                }
-                                else {
-                                    idx = i;
-                                }
-                            }
-                        }
-                        else if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri) && (i - idx >= 2 && i - idx != 3 && 
-                            i < length && pUriString[i] != '?' && pUriString[i] != '#'))
-                        {
-                            // see VsWhidbey#226745 V1.0 did not support file:///, fixing it with minimal behavior change impact
-                            // Only FILE scheme may have UNC Path flag set
-                            m_Flags |= Flags.UncPath;
-                            idx = i;
-                        }
-                    }
-                }
-#endif // !PLATFORM_UNIX
-                //
-                //STEP 1.5 decide on the Authority component
-                //
-#if !PLATFORM_UNIX
-                if ((m_Flags & (Flags.UncPath|Flags.DosPath)) != 0) {
-                }
-#else
-                if ((m_Flags & Flags.ImplicitFile) != 0) {
-                    // Already parsed up to the path
-                }
-#endif // !PLATFORM_UNIX
-                else if ((idx+2) <= length) {
-                    char first  = pUriString[idx];
-                    char second = pUriString[idx+1];
-
-                    if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority)) {
-                        // (V1.0 compatiblity) This will allow http:\\ http:\/ http:/\
-#if !PLATFORM_UNIX
-                        if ((first == '/' || first == '\\') && (second == '/' || second == '\\'))
-#else
-                        if (first == '/' && second == '/')
-#endif // !PLATFORM_UNIX
-                        {
-                            m_Flags |= Flags.AuthorityFound;
-                            idx+=2;
-                        }
-                        else {
-                            return ParsingError.BadAuthority;
-                        }
-                    }
-                    else if (m_Syntax.InFact(UriSyntaxFlags.OptionalAuthority) && (InFact(Flags.AuthorityFound) || 
-                        (first == '/' && second == '/'))) {
-                        m_Flags |= Flags.AuthorityFound;
-                        idx+=2;
-                    }
-                    // 
-                    else if (m_Syntax.NotAny(UriSyntaxFlags.MailToLikeUri)) {
-                        // By now we know the URI has no Authority, so if the URI must be normalized, initialize it without one.
-                        if (m_iriParsing && (m_Flags & Flags.HasUnicode) != 0 && (m_Flags & Flags.HostUnicodeNormalized) == 0)
-                        {
-                            m_String = m_String.Substring(0, idx);
-                        }
-                        // Since there is no Authority, the path index is just the end of the scheme.
-                        m_Flags |= ((Flags)idx | Flags.UnknownHostType);
-                        return ParsingError.None;
-                    }
-                }
-                else if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority)) {
-                    return ParsingError.BadAuthority;
-                }
-                // 
-                else if (m_Syntax.NotAny(UriSyntaxFlags.MailToLikeUri)) {
-                    // By now we know the URI has no Authority, so if the URI must be normalized, initialize it without one.
-                    if (m_iriParsing && (m_Flags & Flags.HasUnicode) != 0 && (m_Flags & Flags.HostUnicodeNormalized) == 0)
-                    {
-                        m_String = m_String.Substring(0, idx);
-                    }
-                    // Since there is no Authority, the path index is just the end of the scheme.
-                    m_Flags |= ((Flags)idx | Flags.UnknownHostType);
-                    return ParsingError.None;
-                }
-
-#if !PLATFORM_UNIX
-                // The following sample taken from the original parser comments makes the whole story sad
-                // vsmacros://c:\path\file
-                // Note that two slashes say there must be an Authority but instead the path goes
-                // Fro V1 compat the next block allow this case but not for schemes like http
-                if (InFact(Flags.DosPath)) {
-
-                    m_Flags |= (((m_Flags & Flags.AuthorityFound)!= 0)? Flags.BasicHostType :Flags.UnknownHostType);
-                    m_Flags |= (Flags)idx;
-                    return ParsingError.None;
-                }
-#endif // !PLATFORM_UNIX
-
-                //STEP 2: Check the syntax of authority expecting at least one character in it
-                //
-                // Note here we do know that there is an authority in the string OR it's a DOS path
-
-                // We may find a userInfo and the port when parsing an authority
-                // Also we may find a registry based authority.
-                // We must ensure that known schemes do use a server-based authority
-            {
-                ParsingError err = ParsingError.None;
-                idx = CheckAuthorityHelper(pUriString, idx, (ushort)length, ref err, ref m_Flags, m_Syntax, ref newHost);
-                if (err != ParsingError.None)
-                    return err;
-
-                // This will disallow '\' as the host terminator for any scheme that is not implicitFile or cannot have a Dos Path
-                if ((idx < (ushort)length && pUriString[idx] == '\\') && NotAny(Flags.ImplicitFile) && 
-                    m_Syntax.NotAny(UriSyntaxFlags.AllowDOSPath)) {
-                    return ParsingError.BadAuthorityTerminator;
-                }
-
-            }
-
-                // The Path (or Port) parsing index is reloaded on demand in CreateUriInfo when accessing a Uri property
-                m_Flags |= (Flags)idx;
-
-                // The rest of the string will be parsed on demand
-                // The Host/Authorty is all checked, the type is known but the host value string
-                // is not created/canonicalized at this point.
-            }
-
-            if((s_IdnScope != UriIdnScope.None) || m_iriParsing)
-                PrivateParseMinimalIri(newHost, idx);
-
-            return ParsingError.None;
-        }
-
-        private void PrivateParseMinimalIri(string newHost, ushort idx)
-        {
-            // we have a new host!
-            if (newHost != null)
-                m_String = newHost;
-
-            // conditions where we dont need to go to parseremaining, so we copy the rest of the
-            // original string.. and switch offsets
-            if ((!m_iriParsing && AllowIdn && (((m_Flags & Flags.IdnHost) != 0) || ((m_Flags & Flags.UnicodeHost) != 0))) ||
-                (m_iriParsing && ((m_Flags & Flags.HasUnicode) == 0) && AllowIdn && ((m_Flags & Flags.IdnHost) != 0))){
-                // update the start of path from the end of new string
-                m_Flags &= ~(Flags.IndexMask);
-                m_Flags |= (Flags)m_String.Length;
-
-                m_String += m_originalUnicodeString.Substring(idx, m_originalUnicodeString.Length - idx);
-            }
-
-            // Indicate to createuriinfo that offset is in m_originalUnicodeString
-            if (m_iriParsing && ((m_Flags & Flags.HasUnicode) != 0)){
-                // offset in Flags.IndexMask refers to m_originalUnicodeString
-                m_Flags |= Flags.UseOrigUncdStrOffset;
-            }
-        }
-
-        //
-        //
-        // The method is called when we have to access m_Info members
-        // This will create the m_Info based on the copied parser context
-        // Under milti-threading ---- this method may do duplicated yet harmless work
-        //
-        private unsafe void CreateUriInfo(Flags cF) {
-
-            UriInfo info = new UriInfo();
-
-            // This will be revisited in ParseRemaining but for now just have it at least m_String.Length
-            info.Offset.End = (ushort)m_String.Length;
-
-            if (UserDrivenParsing)
-                goto Done;
-
-            ushort idx;
-            bool notCanonicalScheme = false;
-
-            // The m_String may have leading spaces, figure that out
-            // plus it will set idx value for next steps
-            if ((cF & Flags.ImplicitFile) != 0) {
-                idx = (ushort)0;
-                while (IsLWS(m_String[idx])) {
-                    ++idx;
-                    ++info.Offset.Scheme;
-                }
-
-#if !PLATFORM_UNIX
-                if (StaticInFact(cF, Flags.UncPath)) {
-                    // For implicit file AND Unc only
-                    idx += 2;
-                    //skip any other slashes (compatibility with V1.0 parser)
-                    while(idx < (ushort)(cF & Flags.IndexMask) && (m_String[idx] == '/' || m_String[idx] == '\\')) {
-                        ++idx;
-                    }
-                }
-#endif // !PLATFORM_UNIX
-            }
-            else {
-                // This is NOT an ImplicitFile uri
-                idx = (ushort)m_Syntax.SchemeName.Length;
-
-                while (m_String[idx++] != ':') {
-                    ++info.Offset.Scheme;
-                }
-
-                if ((cF & Flags.AuthorityFound) != 0)
-                {
-                    if (m_String[idx] == '\\' || m_String[idx+1] == '\\')
-                        notCanonicalScheme = true;
-
-                    idx+=2;
-#if !PLATFORM_UNIX
-                    if ((cF & (Flags.UncPath|Flags.DosPath)) != 0) {
-                        // Skip slashes if it was allowed during ctor time
-                        // NB: Today this is only allowed if a Unc or DosPath was found after the scheme
-                        while( idx < (ushort)(cF & Flags.IndexMask) && (m_String[idx] == '/' || m_String[idx] == '\\')) {
-                            notCanonicalScheme = true;
-                            ++idx;
-                        }
-                    }
-#endif // !PLATFORM_UNIX
-                }
-            }
-
-            // This is weird but some schemes (mailto) do not have Authority-based syntax, still they do have a port
-            if (m_Syntax.DefaultPort != UriParser.NoDefaultPort)
-                info.Offset.PortValue = (ushort)m_Syntax.DefaultPort;
-
-            //Here we set the indexes for already parsed components
-            if ((cF & Flags.HostTypeMask) == Flags.UnknownHostType
-#if !PLATFORM_UNIX
-                || StaticInFact(cF, Flags.DosPath)
-#endif // !PLATFORM_UNIX
-                ) {
-                //there is no Authotity component defined
-                info.Offset.User  = (ushort) (cF & Flags.IndexMask);
-                info.Offset.Host = info.Offset.User;
-                info.Offset.Path = info.Offset.User;
-                cF &= ~Flags.IndexMask;
-                if (notCanonicalScheme) {
-                    cF |= Flags.SchemeNotCanonical;
-                }
-                goto Done;
-            }
-
-            info.Offset.User = idx;
-
-            //Basic Host Type does not have userinfo and port
-            if (HostType == Flags.BasicHostType) {
-                info.Offset.Host = idx;
-                info.Offset.Path = (ushort) (cF & Flags.IndexMask);
-                cF &= ~Flags.IndexMask;
-                goto Done;
-            }
-
-            if ((cF & Flags.HasUserInfo) != 0) {
-                // we previously found a userinfo, get it again
-                while (m_String[idx] != '@') {
-                    ++idx;
-                }
-                ++idx;
-                info.Offset.Host = idx;
-            }
-            else {
-                info.Offset.Host = idx;
-            }
-
-            //Now reload the end of the parsed host
-
-            idx = (ushort) (cF & Flags.IndexMask);
-
-            //From now on we do not need IndexMask bits, and reuse the space for X_NotCanonical flags
-            //clear them now
-            cF &= ~Flags.IndexMask;
-
-            // If this is not canonical, don't count on user input to be good
-            if (notCanonicalScheme) {
-                cF |= Flags.SchemeNotCanonical;
-            }
-
-            //Guessing this is a path start
-            info.Offset.Path = idx;
-
-            // parse Port if any. The new spec allows a port after ':' to be empty (assuming default?)
-            bool notEmpty = false;
-            // Note we already checked on general port syntax in ParseMinimal()
-
-            // If iri parsing is on with unicode chars then the end of parsed host
-            // points to m_orig string and not m_String
-
-            bool UseOrigUnicodeStrOffset = ((cF& Flags.UseOrigUncdStrOffset) != 0);
-            // This should happen only once. Reset it
-            cF &= ~Flags.UseOrigUncdStrOffset;
-
-            if (UseOrigUnicodeStrOffset)
-                info.Offset.End = (ushort)m_originalUnicodeString.Length;
-
-            if (idx < info.Offset.End ){
-                fixed (char* userString = UseOrigUnicodeStrOffset ? m_originalUnicodeString : m_String){
-                    if (userString[idx] == ':'){
-                        int port = 0;
-
-                        //Check on some noncanonical cases http://host:0324/, http://host:03, http://host:0, etc
-                        if (++idx < info.Offset.End){
-                            port = (ushort)(userString[idx] - '0');
-                            if (!(port == unchecked((ushort)('/' - '0')) || port == (ushort)('?' - '0') || 
-                                port == unchecked((ushort)('#' - '0')))) {
-                                notEmpty = true;
-                                if (port == 0){
-                                    cF |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
-                                }
-                                for (++idx; idx < info.Offset.End; ++idx){
-                                    ushort val = (ushort)((ushort)userString[idx] - (ushort)'0');
-                                    if (val == unchecked((ushort)('/' - '0')) || val == (ushort)('?' - '0') || 
-                                        val == unchecked((ushort)('#' - '0'))){
-                                        break;
-                                    }
-                                    port = (port * 10 + val);
-                                }
-                            }
-                        }
-                        if (notEmpty && info.Offset.PortValue != (ushort)port){
-                            info.Offset.PortValue = (ushort)port;
-                            cF |= Flags.NotDefaultPort;
-                        }
-                        else{
-                            //This will tell that we do have a ':' but the port value does
-                            //not follow to canonical rules
-                            cF |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
-                        }
-                        info.Offset.Path = (ushort)idx;
-                    }
-                }
-            }
-
-        Done:
-            cF |= Flags.MinimalUriInfoSet;
-/*********
-            // The spinlock would be better than below lock but it's too late for Beta2, consider for RTM
-            // Also DON'T forget to check EnsureUriInfo method
-            int copyF = m_Flags;
-            while ((copyF & Flags.MinimalUriInfoSet) == 0)
-            {
-               if (copyF != (copyF = Interlocked.CompareExchange(ref m_Flags, cF | (copyF & ~Flags.IndexMask), copyF))
-                   continue;
-               m_Info  = info;
-            }
-*********/
-            info.DnsSafeHost = m_DnsSafeHost;
-            lock (m_String)
-            {
-                if (( m_Flags & Flags.MinimalUriInfoSet) == 0)
-                {
-                    m_Info  = info;
-                    m_Flags = (m_Flags & ~Flags.IndexMask) | cF;
-                }
-            }
-
-        }
-
-        //
-        // This will create a Host string. The validity has been already checked
-        //
-        // Assuming: UriInfo memeber is already set at this point
-        private unsafe void CreateHostString() {
-            //
-            // Mutlithrreading!
-            //
-            if (!m_Syntax.IsSimple)
-            {
-                lock (m_Info)
-                {
-                    // ATTN: Avoid possible recursion through 
-                    // CreateHostString->Syntax.GetComponents->Uri.GetComponentsHelper->CreateHostString
-                    if (NotAny(Flags.ErrorOrParsingRecursion))
-                    {
-                        m_Flags |= Flags.ErrorOrParsingRecursion;
-                        // Need to get host string through the derived type
-                        GetHostViaCustomSyntax();
-                        m_Flags &= ~Flags.ErrorOrParsingRecursion;
-                        return;
-                    }
-                }
-            }
-            Flags flags = m_Flags;
-            string host = CreateHostStringHelper(m_String, m_Info.Offset.Host, m_Info.Offset.Path, ref flags, ref m_Info.ScopeId);
-
-            // now check on canonical host representation
-            if (host.Length != 0)
-            {
-                // An Authority may need escaping except when it's an inet server address
-                //
-                // We do not escape UNC names and will get rid of this type when switching to IDN spec
-                //
-                if (HostType == Flags.BasicHostType) {
-                    ushort idx = 0;
-                    Check result;
-                    fixed (char* pHost = host) {
-                        result = CheckCanonical(pHost, ref idx, (ushort)host.Length, c_DummyChar);
-                    }
-
-                    if ((result & Check.DisplayCanonical) == 0) {
-                        // For implicit file the user string must be in perfect display format,
-                        // Hence, ignoring complains from CheckCanonical()
-                        if (NotAny(Flags.ImplicitFile) || (result & Check.ReservedFound) != 0) {
-                            flags |= Flags.HostNotCanonical;
-                        }
-                    }
-
-                    if (InFact(Flags.ImplicitFile) && (result & (Check.ReservedFound | Check.EscapedCanonical)) != 0) {
-                        // need to re-escape this host if any escaped sequence was found
-                        result &= ~Check.EscapedCanonical;
-                    }
-
-                    if ((result & (Check.EscapedCanonical|Check.BackslashInPath)) != Check.EscapedCanonical) {
-                        // we will make a canonical host in m_Info.Host, but mark that m_String holds wrong data
-                        flags |= Flags.E_HostNotCanonical;
-                        if (NotAny(Flags.UserEscaped))
-                        {
-                            int position = 0;
-                            char[] dest = UriHelper.EscapeString(host, 0, host.Length, null, ref position, true, '?',
-                                '#', IsImplicitFile ? c_DummyChar : '%');
-                            if ((object)dest != null)
-                                host = new string(dest, 0, position);
-                        }
-                        else {
-                            // 
-
-                        }
-                    }
-                }
-                else if (NotAny(Flags.CanonicalDnsHost)){
-                    // Check to see if we can take the canonical host string out of m_String
-                    if ((object)m_Info.ScopeId != null) {
-                        // IPv6 ScopeId is included when serializing a Uri
-                        flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
-                    }
-                    else {
-                        for (int i=0 ; i < host.Length; ++i) {
-                             if ((m_Info.Offset.Host + i) >= m_Info.Offset.End || 
-                                 host[i] != m_String[m_Info.Offset.Host + i]) {
-                                 flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
-                                 break;
-                             }
-                         }
-                    }
-                }
-            }
-
-            m_Info.Host = host;
-            lock (m_Info)
-            {
-                m_Flags |= flags;
-            }
-        }
-        //
-        private static string CreateHostStringHelper(string str, ushort idx, ushort end, ref Flags flags, ref string scopeId)
-        {
-            bool loopback = false;
-            string host;
-            switch (flags & Flags.HostTypeMask) {
-
-                case Flags.DnsHostType:
-                    host = DomainNameHelper.ParseCanonicalName(str, idx, end, ref loopback);
-                    break;
-
-                case Flags.IPv6HostType:
-                    //Microsoft codereview
-                    // The helper will return [...] string that is not suited for Dns.Resolve()
-                    host = IPv6AddressHelper.ParseCanonicalName(str, idx, ref loopback, ref scopeId);
-                    break;
-
-                case Flags.IPv4HostType:
-                    host = IPv4AddressHelper.ParseCanonicalName(str, idx, end, ref loopback);
-                    break;
-
-#if !PLATFORM_UNIX
-                case Flags.UncHostType:
-                    host = UncNameHelper.ParseCanonicalName(str, idx, end, ref loopback);
-                    break;
-#endif // !PLATFORM_UNIX
-
-                case Flags.BasicHostType:
-#if !PLATFORM_UNIX
-                    if (StaticInFact(flags, Flags.DosPath)) {
-                        host = string.Empty;
-                    }
-                    else
-#endif // !PLATFORM_UNIX
-                    {
-                        // This is for a registry-based authority, not relevant for known schemes
-                        host = str.Substring(idx, end-idx);
-                    }
-                    // A empty host would count for a loopback
-                    if (host.Length == 0) {
-                        loopback = true;
-                    }
-                    //there will be no port
-                    break;
-
-                case Flags.UnknownHostType:
-                    //means the host is *not expected* for this uri type
-                    host = string.Empty;
-                    break;
-
-                default: //it's a bug
-                    throw GetException(ParsingError.BadHostName);
-            }
-
-            if (loopback) {
-                flags |= Flags.LoopbackHost;
-            }
-            return host;
-        }
-        //
-        // Called under lock()
-        //
-        private unsafe void GetHostViaCustomSyntax()
-        {
-            // A multithreading check
-            if (m_Info.Host != null)
-                return;
-
-            string host = m_Syntax.InternalGetComponents(this, UriComponents.Host, UriFormat.UriEscaped);
-
-            // ATTN: Check on whether recursion has not happened
-            if ((object)m_Info.Host == null)
-            {
-                if (host.Length >= c_MaxUriBufferSize)
-                    throw GetException(ParsingError.SizeLimit);
-
-                ParsingError err = ParsingError.None;
-                Flags flags = m_Flags & ~Flags.HostTypeMask;
-
-                fixed (char *pHost = host)
-                {
-                    string newHost = null;
-                    if (CheckAuthorityHelper(pHost, 0, (ushort)host.Length, ref err, ref flags, m_Syntax, ref newHost) != 
-                        (ushort)host.Length)
-                    {
-                        // We cannot parse the entire host string
-                        flags &= ~Flags.HostTypeMask;
-                        flags |= Flags.UnknownHostType;
-                    }
-                }
-
-                if (err != ParsingError.None || (flags & Flags.HostTypeMask) == Flags.UnknownHostType)
-                {
-                    // Well, custom parser has returned a not known host type, take it as Basic then.
-                    m_Flags = (m_Flags & ~Flags.HostTypeMask) | Flags.BasicHostType;
-                }
-                else
-                {
-                    host = CreateHostStringHelper(host, 0, (ushort)host.Length, ref flags, ref m_Info.ScopeId);
-                    for (int i=0 ; i < host.Length; ++i) {
-                             if ((m_Info.Offset.Host + i) >= m_Info.Offset.End || host[i] != m_String[m_Info.Offset.Host + i]) {
-                                 m_Flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
-                                 break;
-                             }
-                         }
-                    m_Flags = (m_Flags & ~Flags.HostTypeMask) | (flags & Flags.HostTypeMask);
-                }
-            }
-            //
-            // This is a chance for a custom parser to report a different port value
-            //
-            string portStr = m_Syntax.InternalGetComponents(this, UriComponents.StrongPort, UriFormat.UriEscaped);
-            int port = 0;
-            if ((object)portStr == null || portStr.Length == 0)
-            {
-                // It's like no port
-                m_Flags &= ~Flags.NotDefaultPort;
-                m_Flags |= (Flags.PortNotCanonical|Flags.E_PortNotCanonical);
-                m_Info.Offset.PortValue = 0;
-            }
-            else
-            {
-                for (int idx=0; idx < portStr.Length; ++idx)
-                {
-                    int val = portStr[idx] - '0';
-                    if (val < 0 || val > 9 || (port = (port * 10 + val)) > 0xFFFF)
-                        throw new UriFormatException(SR.GetString(SR.net_uri_PortOutOfRange, m_Syntax.GetType().FullName, portStr));
-                }
-                if (port != m_Info.Offset.PortValue)
-                {
-                    if (port == m_Syntax.DefaultPort)
-                        m_Flags &= ~Flags.NotDefaultPort;
-                    else
-                        m_Flags |= Flags.NotDefaultPort;
-
-                    m_Flags |= (Flags.PortNotCanonical|Flags.E_PortNotCanonical);
-                    m_Info.Offset.PortValue = (ushort) port;
-                }
-            }
-            // This must be done as the last thing in this method
-            m_Info.Host = host;
-        }
-        //
-        // An internal shortcut into Uri extenisiblity API
-        //
-        internal string GetParts(UriComponents uriParts, UriFormat formatAs)
-        {
-            return GetComponents(uriParts, formatAs);
-        }
-
-        //
-        //
-        //
-        private string GetEscapedParts(UriComponents uriParts) {
-            // Which Uri parts are not escaped canonically ?
-            // Notice that public UriPart and private Flags must me in Sync so below code can work
-            //
-            ushort  nonCanonical = (ushort)(((ushort)m_Flags & ((ushort)Flags.CannotDisplayCanonical<<7)) >> 6);
-            if (InFact(Flags.SchemeNotCanonical)) {
-                nonCanonical |= (ushort)Flags.SchemeNotCanonical;
-            }
-
-            // We keep separate flags for some of path canonicalization facts
-            if ((uriParts & UriComponents.Path) != 0) {
-                if (InFact(Flags.ShouldBeCompressed|Flags.FirstSlashAbsent|Flags.BackslashInPath)) {
-                    nonCanonical |= (ushort)Flags.PathNotCanonical;
-                }
-                else if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] == '|') {
-                    // A rare case of c|\
-                    nonCanonical |= (ushort)Flags.PathNotCanonical;
-                }
-            }
-
-            if (((ushort)uriParts & nonCanonical) == 0) {
-                string ret = GetUriPartsFromUserString(uriParts);
-                if ((object)ret != null) {
-                    return ret;
-                }
-            }
-
-            return ReCreateParts(uriParts, nonCanonical, UriFormat.UriEscaped);
-        }
-
-        private string GetUnescapedParts(UriComponents uriParts, UriFormat formatAs) {
-            // Which Uri parts are not escaped canonically ?
-            // Notice that public UriComponents and private Uri.Flags must me in Sync so below code can work
-            //
-            ushort  nonCanonical = (ushort)((ushort)m_Flags & (ushort)Flags.CannotDisplayCanonical);
-
-            // We keep separate flags for some of path canonicalization facts
-            if ((uriParts & UriComponents.Path) != 0) {
-                if ((m_Flags & (Flags.ShouldBeCompressed|Flags.FirstSlashAbsent|Flags.BackslashInPath)) !=0) {
-                    nonCanonical |= (ushort)Flags.PathNotCanonical;
-                }
-                else if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] == '|') {
-                    // A rare case of c|\
-                    nonCanonical |= (ushort)Flags.PathNotCanonical;
-                }
-
-            }
-
-            if (((ushort)uriParts & nonCanonical) == 0) {
-                string ret = GetUriPartsFromUserString(uriParts);
-                if ((object)ret != null) {
-                    return ret;
-                }
-            }
-
-            return ReCreateParts(uriParts, nonCanonical, formatAs);
-        }
-
-        //
-        //
-        //
-        private string ReCreateParts(UriComponents parts, ushort nonCanonical, UriFormat formatAs)
-        {
-            // going hard core
-            EnsureHostString(false);
-            string stemp = (parts & UriComponents.Host) == 0? string.Empty: m_Info.Host;
-            // we reserve more space than required because a canonical Ipv6 Host
-            // may take more characteres than in original m_String
-            // Also +3 is for :// and +1 is for absent first slash
-            // Also we may escape every character, hence multiplying by 12
-            // UTF-8 can use up to 4 bytes per char * 3 chars per byte (%A4) = 12 encoded chars
-            int count = (m_Info.Offset.End-m_Info.Offset.User) * (formatAs == UriFormat.UriEscaped?12:1);
-            char[] chars = new char[stemp.Length + count + m_Syntax.SchemeName.Length + 3 + 1];
-            count = 0;
-
-            //Scheme and slashes
-            if ((parts & UriComponents.Scheme) != 0) {
-                m_Syntax.SchemeName.CopyTo(0, chars, count, m_Syntax.SchemeName.Length);
-                count += m_Syntax.SchemeName.Length;
-                if (parts != UriComponents.Scheme) {
-                    chars[count++] = ':';
-                    if (InFact(Flags.AuthorityFound)) {
-                        chars[count++] = '/';
-                        chars[count++] = '/';
-                    }
-                }
-            }
-
-            //UserInfo
-            if ((parts & UriComponents.UserInfo) != 0 && InFact(Flags.HasUserInfo))
-            {
-                if ((nonCanonical & (ushort)UriComponents.UserInfo) != 0) {
-                    switch (formatAs) {
-                        case UriFormat.UriEscaped:
-                            if (NotAny(Flags.UserEscaped))
-                            {
-                                chars = UriHelper.EscapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, chars, 
-                                    ref count, true, '?', '#', '%');
-                            }
-                            else {
-                                if (InFact(Flags.E_UserNotCanonical)) {
-                                    // 
-
-                                }
-                                m_String.CopyTo(m_Info.Offset.User, chars, count, m_Info.Offset.Host - m_Info.Offset.User);
-                                count += (m_Info.Offset.Host - m_Info.Offset.User);
-                            }
-                            break;
-
-                        case UriFormat.SafeUnescaped:
-                            chars = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host - 1, 
-                                chars, ref count, '@', '/', '\\', InFact(Flags.UserEscaped) ? UnescapeMode.Unescape :
-                                UnescapeMode.EscapeUnescape, m_Syntax, false);
-                            chars[count++] = '@';
-                            break;
-
-                        case UriFormat.Unescaped:
-                            chars = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, chars, 
-                                ref count, c_DummyChar, c_DummyChar, c_DummyChar, 
-                                UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, false);
-                            break;
-
-                        default: //V1ToStringUnescape
-                            chars = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, chars, 
-                                ref count, c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, 
-                                false);
-                            break;
-                    }
-                }
-                else {
-                    UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, chars, ref count, 
-                        c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, false);
-                }
-                if (parts == UriComponents.UserInfo)
-                {
-                    //strip '@' delimiter
-                    --count;
-                }
-            }
-
-            // Host
-            if ((parts & UriComponents.Host) != 0 && stemp.Length != 0)
-            {
-                UnescapeMode mode;
-                if (formatAs != UriFormat.UriEscaped && HostType == Flags.BasicHostType 
-                    && (nonCanonical & (ushort)UriComponents.Host) != 0) {
-                    // only Basic host could be in the escaped form
-                    mode = formatAs == UriFormat.Unescaped
-                        ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) :
-                            (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape);
-
-                }
-                else {
-                    mode = UnescapeMode.CopyOnly;
-                }
-                // NormalizedHost
-                if ((parts & UriComponents.NormalizedHost) != 0)
-                {
-                    unsafe
-                    {
-                        fixed (char* hostPtr = stemp)
-                        {
-                            bool allAscii = false;
-                            bool atLeastOneValidIdn = false;
-                            try
-                            {
-                                // Upconvert any punycode to unicode, xn--pck -> ?
-                                stemp = DomainNameHelper.UnicodeEquivalent(
-                                    hostPtr, 0, stemp.Length, ref allAscii, ref atLeastOneValidIdn);
-                            }
-                            // The host may be invalid punycode (www.xn--?-pck.com), 
-                            // but we shouldn't throw after the constructor.
-                            catch (UriFormatException) { }
-                        }
-                    }
-                }
-                chars = UriHelper.UnescapeString(stemp, 0, stemp.Length, chars, ref count, '/', '?', '#', mode, 
-                    m_Syntax, false);
-
-                // A fix up only for SerializationInfo and IpV6 host with a scopeID
-                if ((parts & UriComponents.SerializationInfoString) != 0 && HostType == Flags.IPv6HostType && 
-                    (object)m_Info.ScopeId != null)
-                {
-                    m_Info.ScopeId.CopyTo(0, chars, count-1, m_Info.ScopeId.Length);
-                    count += m_Info.ScopeId.Length;
-                    chars[count-1] = ']';
-                }
-            }
-
-            //Port (always wants a ':' delimiter if got to this method)
-            if ((parts & UriComponents.Port) != 0)
-            {
-                if ((nonCanonical & (ushort)UriComponents.Port) == 0) {
-                    //take it from m_String
-                    if (InFact(Flags.NotDefaultPort)) {
-                        ushort start = m_Info.Offset.Path;
-                        while (m_String[--start] != ':') {
-                            ;
-                        }
-                        m_String.CopyTo(start, chars, count, m_Info.Offset.Path - start);
-                        count += (m_Info.Offset.Path - start);
-                    }
-                    else if ((parts & UriComponents.StrongPort) != 0 && m_Syntax.DefaultPort != UriParser.NoDefaultPort) {
-                        chars[count++]= ':';
-                        stemp = m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
-                        stemp.CopyTo(0, chars, count, stemp.Length);
-                        count += stemp.Length;
-                    }
-                }
-                else if (InFact(Flags.NotDefaultPort) || ((parts & UriComponents.StrongPort) != 0 && 
-                    m_Syntax.DefaultPort != UriParser.NoDefaultPort)) {
-                    // recreate string from port value
-                    chars[count++]= ':';
-                    stemp = m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
-                    stemp.CopyTo(0, chars, count, stemp.Length);
-                    count += stemp.Length;
-                }
-            }
-
-            ushort delimiterAwareIndex;
-
-            //Path
-            if ((parts & UriComponents.Path) != 0)
-            {
-                chars = GetCanonicalPath(chars, ref count, formatAs);
-
-                // (possibly strip the leading '/' delimiter)
-                if (parts == UriComponents.Path)
-                {
-                    if (InFact(Flags.AuthorityFound) && count !=0 && chars[0] == '/')
-                    {
-                        delimiterAwareIndex = 1; --count;
-                    }
-                    else
-                    {
-                        delimiterAwareIndex = 0;
-                    }
-                    return count == 0? string.Empty: new string(chars, delimiterAwareIndex, count);
-                }
-            }
-
-            //Query (possibly strip the '?' delimiter)
-            if ((parts & UriComponents.Query) != 0 && m_Info.Offset.Query < m_Info.Offset.Fragment)
-            {
-                delimiterAwareIndex = (ushort)(m_Info.Offset.Query+1);
-                if(parts != UriComponents.Query)
-                    chars[count++] = '?';   //see Fragment+1 below
-
-                if ((nonCanonical & (ushort)UriComponents.Query) != 0)
-                {
-                    switch (formatAs)
-                    {
-                    case UriFormat.UriEscaped:
-                        //Can Assert IsImplicitfile == false
-                        if (NotAny(Flags.UserEscaped))
-                            chars = UriHelper.EscapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
-                                ref count, true, '#', c_DummyChar, '%');
-                        else
-                        {
-                            // 
-
-
-                            UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
-                                ref count, c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, 
-                                true);
-                        }
-                        break;
-
-                    case V1ToStringUnescape:
-
-                        chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
-                            ref count, '#', c_DummyChar, c_DummyChar, (InFact(Flags.UserEscaped) ?
-                            UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) | UnescapeMode.V1ToStringFlag, 
-                            m_Syntax, true);
-                        break;
-
-                    case UriFormat.Unescaped:
-
-                        chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
-                            ref count, '#', c_DummyChar, c_DummyChar, 
-                            (UnescapeMode.Unescape | UnescapeMode.UnescapeAll), m_Syntax, true);
-                        break;
-
-                    default: // UriFormat.SafeUnescaped
-
-                        chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
-                            ref count, '#', c_DummyChar, c_DummyChar, (InFact(Flags.UserEscaped) ?
-                            UnescapeMode.Unescape : UnescapeMode.EscapeUnescape), m_Syntax, true);
-                        break;
-                    }
-                }
-                else
-                {
-                    UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, ref count, 
-                        c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, true);
-                }
-            }
-
-            //Fragment (possibly strip the '#' delimiter)
-            if ((parts & UriComponents.Fragment) != 0 && m_Info.Offset.Fragment < m_Info.Offset.End)
-            {
-                delimiterAwareIndex = (ushort)(m_Info.Offset.Fragment+1);
-                if(parts != UriComponents.Fragment)
-                    chars[count++] = '#';   //see Fragment+1 below
-
-                if ((nonCanonical & (ushort)UriComponents.Fragment) != 0)
-                {
-                    switch (formatAs) {
-                    case UriFormat.UriEscaped:
-                            if (NotAny(Flags.UserEscaped))
-                                chars = UriHelper.EscapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars,
-                                    ref count, true, UriParser.ShouldUseLegacyV2Quirks ? '#' : c_DummyChar, c_DummyChar, '%');
-                            else
-                            {
-                                // 
-
-
-                                UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, 
-                                    ref count, c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, 
-                                    false);
-                            }
-                            break;
-
-                    case V1ToStringUnescape:
-
-                            chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, 
-                                ref count, '#', c_DummyChar, c_DummyChar, (InFact(Flags.UserEscaped) ?
-                                UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) | UnescapeMode.V1ToStringFlag, 
-                                m_Syntax, false);
-                        break;
-                    case UriFormat.Unescaped:
-
-                        chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, 
-                            ref count, '#', c_DummyChar, c_DummyChar, 
-                            UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, false);
-                        break;
-
-                    default: // UriFormat.SafeUnescaped
-
-                        chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, 
-                            ref count, '#', c_DummyChar, c_DummyChar, (InFact(Flags.UserEscaped) ?
-                            UnescapeMode.Unescape : UnescapeMode.EscapeUnescape), m_Syntax, false);
-                        break;
-                    }
-                }
-                else
-                {
-                    UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, ref count, 
-                        c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, false);
-                }
-            }
-
-            return new string(chars, 0, count);
-        }
-
-        //
-        // This method is called only if the user string has a canonical representation
-        // of requested parts
-        //
-        private string GetUriPartsFromUserString(UriComponents uriParts) {
-
-            ushort delimiterAwareIdx;
-
-            switch (uriParts & ~UriComponents.KeepDelimiter) {
-                    // For FindServicePoint perf
-                case UriComponents.Scheme | UriComponents.Host | UriComponents.Port:
-                    if (!InFact(Flags.HasUserInfo))
-                        return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Path - m_Info.Offset.Scheme);
-
-                    return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme)
-                         + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host);
-
-                    // For HttpWebRequest.ConnectHostAndPort perf
-                case UriComponents.HostAndPort:  //Host|StrongPort
-
-                    if (!InFact(Flags.HasUserInfo))
-                        goto case UriComponents.StrongAuthority;
-
-                    if (InFact(Flags.NotDefaultPort) || m_Syntax.DefaultPort == UriParser.NoDefaultPort)
-                        return m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host);
-
-                    return m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host)
-                        + ':' + m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
-
-                    // For an obvious common case perf
-                case UriComponents.AbsoluteUri:     //Scheme|UserInfo|Host|Port|Path|Query|Fragment,
-                    if (m_Info.Offset.Scheme == 0 && m_Info.Offset.End == m_String.Length)
-                        return m_String;
-
-                    return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.End - m_Info.Offset.Scheme);
-
-                    // For Uri.Equals() and HttpWebRequest through a proxy perf
-                case UriComponents.HttpRequestUrl:   //Scheme|Host|Port|Path|Query,
-                    if (InFact(Flags.HasUserInfo)) {
-                        return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme)
-                            + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Fragment - m_Info.Offset.Host);
-                    }
-                    if (m_Info.Offset.Scheme == 0 && m_Info.Offset.Fragment == m_String.Length)
-                        return m_String;
-
-                    return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Fragment - m_Info.Offset.Scheme);
-
-                    // For CombineUri() perf
-                case UriComponents.SchemeAndServer|UriComponents.UserInfo:
-                    return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Path - m_Info.Offset.Scheme);
-
-                    // For Cache perf
-                case (UriComponents.AbsoluteUri & ~UriComponents.Fragment):
-                    if (m_Info.Offset.Scheme == 0 && m_Info.Offset.Fragment == m_String.Length)
-                        return m_String;
-
-                    return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Fragment - m_Info.Offset.Scheme);
-
-
-                // Strip scheme delimiter if was not requested
-                case UriComponents.Scheme:
-                        if (uriParts != UriComponents.Scheme)
-                            return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme);
-
-                        return m_Syntax.SchemeName;
-
-                // KeepDelimiter makes no sense for this component
-                case UriComponents.Host:
-                    ushort idx = m_Info.Offset.Path;
-                    if (InFact(Flags.NotDefaultPort|Flags.PortNotCanonical)) {
-                        //Means we do have ':' after the host
-                        while (m_String[--idx] != ':')
-                            ;
-                    }
-                    return (idx - m_Info.Offset.Host == 0)? string.Empty: m_String.Substring(m_Info.Offset.Host, 
-                        idx - m_Info.Offset.Host);
-
-                case UriComponents.Path:
-
-                    // Strip the leading '/' for a hierarchical URI if no delimiter was requested
-                    if (uriParts == UriComponents.Path && InFact(Flags.AuthorityFound) &&
-                        m_Info.Offset.End > m_Info.Offset.Path && m_String[m_Info.Offset.Path] == '/')
-                        delimiterAwareIdx = (ushort)(m_Info.Offset.Path + 1);
-                    else
-                        delimiterAwareIdx = m_Info.Offset.Path;
-
-                    if (delimiterAwareIdx >= m_Info.Offset.Query)
-                        return string.Empty;
-
-
-                    return m_String.Substring(delimiterAwareIdx, m_Info.Offset.Query - delimiterAwareIdx);
-
-                case UriComponents.Query:
-                    // Strip the '?' if no delimiter was requested
-                    if (uriParts == UriComponents.Query)
-                        delimiterAwareIdx = (ushort)(m_Info.Offset.Query + 1);
-                    else
-                        delimiterAwareIdx = m_Info.Offset.Query;
-
-                    if (delimiterAwareIdx >= m_Info.Offset.Fragment)
-                        return string.Empty;
-
-                    return m_String.Substring(delimiterAwareIdx, m_Info.Offset.Fragment - delimiterAwareIdx);
-
-                case UriComponents.Fragment:
-                    // Strip the '#' if no delimiter was requested
-                    if (uriParts == UriComponents.Fragment)
-                        delimiterAwareIdx = (ushort)(m_Info.Offset.Fragment + 1);
-                    else
-                        delimiterAwareIdx = m_Info.Offset.Fragment;
-
-                    if (delimiterAwareIdx >= m_Info.Offset.End)
-                        return string.Empty;
-
-                    return m_String.Substring(delimiterAwareIdx, m_Info.Offset.End - delimiterAwareIdx);
-
-                case UriComponents.UserInfo | UriComponents.Host | UriComponents.Port:
-                    return (m_Info.Offset.Path - m_Info.Offset.User == 0) ? string.Empty : 
-                        m_String.Substring(m_Info.Offset.User, m_Info.Offset.Path - m_Info.Offset.User);
-
-                case UriComponents.StrongAuthority:  //UserInfo|Host|StrongPort
-                    if (InFact(Flags.NotDefaultPort) || m_Syntax.DefaultPort == UriParser.NoDefaultPort)
-                        goto case UriComponents.UserInfo | UriComponents.Host | UriComponents.Port;
-
-                    return m_String.Substring(m_Info.Offset.User, m_Info.Offset.Path - m_Info.Offset.User)
-                        + ':' + m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
-
-                case UriComponents.PathAndQuery:        //Path|Query,
-                    return m_String.Substring(m_Info.Offset.Path, m_Info.Offset.Fragment - m_Info.Offset.Path);
-
-                case UriComponents.HttpRequestUrl|UriComponents.Fragment: //Scheme|Host|Port|Path|Query|Fragment,
-                    if (InFact(Flags.HasUserInfo)) {
-                        return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme)
-                            + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.End - m_Info.Offset.Host);
-                    }
-                    if (m_Info.Offset.Scheme == 0 && m_Info.Offset.End == m_String.Length)
-                        return m_String;
-
-                    return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.End - m_Info.Offset.Scheme);
-
-                case UriComponents.PathAndQuery|UriComponents.Fragment:  //LocalUrl|Fragment
-                    return m_String.Substring(m_Info.Offset.Path, m_Info.Offset.End - m_Info.Offset.Path);
-
-                case UriComponents.UserInfo:
-                        // Strip the '@' if no delimiter was requested
-
-                    if (NotAny(Flags.HasUserInfo))
-                        return string.Empty;
-
-                    if (uriParts == UriComponents.UserInfo)
-                        delimiterAwareIdx = (ushort)(m_Info.Offset.Host - 1);
-                    else
-                        delimiterAwareIdx = m_Info.Offset.Host;
-
-                    if (m_Info.Offset.User >= delimiterAwareIdx)
-                        return string.Empty;
-
-                    return m_String.Substring(m_Info.Offset.User, delimiterAwareIdx - m_Info.Offset.User);
-
-                default:
-                    return null;
-            }
-        }
-
-
-        //
-        //This method does:
-        //  - Creates m_Info member
-        //  - checks all componenets up to path on their canonical representation
-        //  - continues parsing starting the path position
-        //  - Sets the offsets of remaining components
-        //  - Sets the Canonicalization flags if applied
-        //  - Will NOT create MoreInfo members
-        //
-        private unsafe void ParseRemaining() {
-
-            // ensure we parsed up to the path
-            EnsureUriInfo();
-
-            Flags cF = Flags.Zero;
-
-            if (UserDrivenParsing)
-                goto Done;
-
-            // Do we have to continue building Iri'zed string from original string
-            bool buildIriStringFromPath = m_iriParsing && ((m_Flags & Flags.HasUnicode) != 0) && ((m_Flags & Flags.RestUnicodeNormalized) == 0);
-
-            ushort origIdx;     // stores index to switched original string
-            ushort idx = m_Info.Offset.Scheme;
-            ushort length = (ushort)m_String.Length;
-            Check result = Check.None;
-            UriSyntaxFlags syntaxFlags = m_Syntax.Flags;    // perf
-
-            // Multithreading!
-            // m_Info.Offset values may be parsed twice but we lock only on m_Flags update.
-
-            fixed (char* str = m_String){
-                // Cut trailing spaces in m_String
-                if (length > idx && IsLWS(str[length - 1]))
-                {
-                    --length;
-                    while (length != idx && IsLWS(str[--length]))
-                        ;
-                    ++length;
-                }
-
-                if (IsImplicitFile){
-                    cF |= Flags.SchemeNotCanonical;
-                }
-                else {
-                    ushort i = 0;
-                    ushort syntaxLength = (ushort)m_Syntax.SchemeName.Length;
-                    for (; i < syntaxLength; ++i)
-                    {
-                        if (m_Syntax.SchemeName[i] != str[idx + i])
-                            cF |= Flags.SchemeNotCanonical;
-                    }
-                    // For an authority Uri only // after the scheme would be canonical
-                    // (compatibility bug http:\\host)
-                    if (((m_Flags & Flags.AuthorityFound) != 0) && (idx + i + 3 >= length || str[idx + i + 1] != '/' || 
-                        str[idx + i + 2] != '/')) 
-                    {
-                        cF |= Flags.SchemeNotCanonical;
-                    }
-                }
-
-
-                //Check the form of the user info
-                if ((m_Flags & Flags.HasUserInfo) != 0){
-                    idx = m_Info.Offset.User;
-                    result = CheckCanonical(str, ref idx, m_Info.Offset.Host, '@');
-                    if ((result & Check.DisplayCanonical) == 0){
-                        cF |= Flags.UserNotCanonical;
-                    }
-                    if ((result & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical){
-                        cF |= Flags.E_UserNotCanonical;
-                    }
-                    if (m_iriParsing && ((result & (Check.DisplayCanonical | Check.EscapedCanonical | Check.BackslashInPath
-                                                    | Check.FoundNonAscii | Check.NotIriCanonical))
-                                                    == (Check.DisplayCanonical | Check.FoundNonAscii))){
-                        cF |= Flags.UserIriCanonical;
-                    }
-                }
-            }
-            //
-            // Delay canonical Host checking to avoid creation of a host string
-            // Will do that on demand.
-            //
-
-
-            //
-            //We have already checked on the port in EnsureUriInfo() that calls CreateUriInfo
-            //
-
-            //
-            // Parsing the Path if any
-            //
-
-            // For iri parsing if we found unicode the idx has offset into m_orig string..
-            // so restart parsing from there and make m_Info.Offset.Path as m_string.length
-
-            idx = m_Info.Offset.Path;
-            origIdx = m_Info.Offset.Path;
-
-            //Some uris do not have a query
-            //    When '?' is passed as delimiter, then it's special case
-            //    so both '?' and '#' will work as delimiters
-            if (buildIriStringFromPath){
-
-                // Dos paths have no host.  Other schemes cleared/set m_String with host information in PrivateParseMinimal.
-                if (IsDosPath) {
-                    if (IsImplicitFile) {
-                        m_String = String.Empty;
-                    }
-                    else {
-                        m_String = m_Syntax.SchemeName + SchemeDelimiter;
-                    }
-                }
-
-                m_Info.Offset.Path = (ushort)m_String.Length;
-                idx = m_Info.Offset.Path;
-
-                ushort offset = origIdx;
-                if (IsImplicitFile || ((syntaxFlags & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) == 0)){
-                    FindEndOfComponent(m_originalUnicodeString, ref origIdx, (ushort)m_originalUnicodeString.Length, c_DummyChar);
-                }
-                else{
-                    FindEndOfComponent(m_originalUnicodeString, ref origIdx, (ushort)m_originalUnicodeString.Length,
-                   (m_Syntax.InFact(UriSyntaxFlags.MayHaveQuery) ? '?' : m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment) ? '#' : c_EOL));
-                }
-
-                // Correctly escape unescape
-                string escapedPath = EscapeUnescapeIri(m_originalUnicodeString, offset, origIdx, UriComponents.Path);
-
-                // Normalize path
-                try{
-                    if (UriParser.ShouldUseLegacyV2Quirks)
-                        m_String += escapedPath.Normalize(NormalizationForm.FormC);
-                    else
-                        m_String += escapedPath;
-                }
-                catch (ArgumentException){
-                    UriFormatException e = GetException(ParsingError.BadFormat);
-                    throw e;
-                }
-
-                if (!ServicePointManager.AllowAllUriEncodingExpansion && m_String.Length > ushort.MaxValue){
-                    UriFormatException e = GetException(ParsingError.SizeLimit);
-                    throw e;
-                }
-
-                length = (ushort)m_String.Length;
-            }
-
-            fixed (char* str = m_String){
-                if (IsImplicitFile || ((syntaxFlags & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) == 0)){
-                    result = CheckCanonical(str, ref idx, length, c_DummyChar);
-                }
-                else {
-                    result = CheckCanonical(str, ref idx, length, (((syntaxFlags & UriSyntaxFlags.MayHaveQuery) != 0) 
-                        ? '?' : m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment) ? '#' : c_EOL));
-                }
-
-                // ATTN:
-                // This may render problems for unknown schemes, but in general for an authority based Uri
-                // (that has slashes) a path should start with "/"
-                // This becomes more interesting knowning how a file uri is used in "file://c:/path"
-                // It will be converted to file:///c:/path
-                //
-                // However, even more interesting is that vsmacros://c:\path will not add the third slash in the _canoical_ case
-                // (vsmacros inventors have violated the RFC)
-                //
-                // We use special syntax flag to check if the path is rooted, i.e. has a first slash
-                //
-                if (((m_Flags & Flags.AuthorityFound) != 0) && ((syntaxFlags & UriSyntaxFlags.PathIsRooted) != 0)
-                    && (m_Info.Offset.Path == length || (str[m_Info.Offset.Path] != '/' && str[m_Info.Offset.Path] != '\\'))){
-                    cF |= Flags.FirstSlashAbsent;
-                }
-            }
-            // Check the need for compression or backslashes conversion
-            // we included IsDosPath since it may come with other than FILE uri, for ex. scheme://C:\path
-            // (This is very unfortunate that the original design has included that feature)
-            bool nonCanonical = false;
-            if (IsDosPath || (((m_Flags & Flags.AuthorityFound) != 0) &&
-                (((syntaxFlags & (UriSyntaxFlags.CompressPath | UriSyntaxFlags.ConvertPathSlashes)) != 0) ||
-                m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes))))
-            {
-                if (((result & Check.DotSlashEscaped) != 0) && m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes))
-                {
-                    cF |= (Flags.E_PathNotCanonical | Flags.PathNotCanonical);
-                    nonCanonical = true;
-                }
-
-                if (((syntaxFlags & (UriSyntaxFlags.ConvertPathSlashes)) != 0) && (result & Check.BackslashInPath) != 0){
-                    cF |= (Flags.E_PathNotCanonical | Flags.PathNotCanonical);
-                    nonCanonical = true;
-                }
-
-                if (((syntaxFlags & (UriSyntaxFlags.CompressPath)) != 0) && ((cF & Flags.E_PathNotCanonical) != 0 ||
-                    (result & Check.DotSlashAttn) != 0)) 
-                {
-                    cF |= Flags.ShouldBeCompressed;
-                }
-
-                if ((result & Check.BackslashInPath) != 0)
-                    cF |= Flags.BackslashInPath;
-
-            }
-            else if ((result & Check.BackslashInPath) != 0){
-                // for a "generic" path '\' should be escaped
-                cF |= Flags.E_PathNotCanonical;
-                nonCanonical = true;
-            }
-
-            if ((result & Check.DisplayCanonical) == 0){
-                // For implicit file the user string is usually in perfect display format,
-                // Hence, ignoring complains from CheckCanonical()
-                //
-
-                if (((m_Flags & Flags.ImplicitFile) == 0) || ((m_Flags & Flags.UserEscaped) != 0) || 
-                    (result & Check.ReservedFound) != 0) {
-                    //means it's found as escaped or has unescaped Reserved Characters
-                    cF |= Flags.PathNotCanonical;
-                    nonCanonical = true;
-                }
-            }
-
-            if (((m_Flags & Flags.ImplicitFile) != 0) && (result & (Check.ReservedFound | Check.EscapedCanonical)) != 0){
-                // need to escape reserved chars or re-escape '%' if an "escaped sequence" was found
-                result &= ~Check.EscapedCanonical;
-            }
-
-            if ((result & Check.EscapedCanonical) == 0){
-                //means it's found as not completely escaped
-                cF |= Flags.E_PathNotCanonical;
-            }
-
-            if (m_iriParsing && !nonCanonical & ((result & (Check.DisplayCanonical | Check.EscapedCanonical
-                            | Check.FoundNonAscii | Check.NotIriCanonical))
-                            == (Check.DisplayCanonical | Check.FoundNonAscii))){
-                cF |= Flags.PathIriCanonical;
-            }
-
-            //
-            //Now we've got to parse the Query if any. Note that Query requires the presence of '?'
-            //
-           if (buildIriStringFromPath){
-               ushort offset = origIdx;
-
-               if (origIdx < m_originalUnicodeString.Length && m_originalUnicodeString[origIdx] == '?'){
-                   ++origIdx; // This is to exclude first '?' character from checking
-                   FindEndOfComponent(m_originalUnicodeString, ref origIdx, (ushort)m_originalUnicodeString.Length, ((syntaxFlags &(UriSyntaxFlags.MayHaveFragment)) != 0) ? '#' : c_EOL);
-
-                   // Correctly escape unescape
-                   string escapedPath = EscapeUnescapeIri(m_originalUnicodeString, offset, origIdx, UriComponents.Query);
-
-                   // Normalize path
-                   try{
-                       if (UriParser.ShouldUseLegacyV2Quirks)
-                           m_String += escapedPath.Normalize(NormalizationForm.FormC);
-                       else
-                           m_String += escapedPath;
-                   }
-                   catch (ArgumentException){
-                       UriFormatException e = GetException(ParsingError.BadFormat);
-                       throw e;
-                   }
-
-                   if (!ServicePointManager.AllowAllUriEncodingExpansion && m_String.Length > ushort.MaxValue){
-                       UriFormatException e = GetException(ParsingError.SizeLimit);
-                       throw e;
-                   }
-
-                   length = (ushort)m_String.Length;
-               }
-            }
-
-            m_Info.Offset.Query = idx;
-
-            fixed (char* str = m_String){
-                if (idx < length && str[idx] == '?'){
-                    ++idx; // This is to exclude first '?' character from checking
-                    result = CheckCanonical(str, ref idx, length, ((syntaxFlags & (UriSyntaxFlags.MayHaveFragment)) != 0) 
-                        ? '#' : c_EOL);
-                    if ((result & Check.DisplayCanonical) == 0){
-                        cF |= Flags.QueryNotCanonical;
-                    }
-
-                    if ((result & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical){
-                        cF |= Flags.E_QueryNotCanonical;
-                    }
-
-                    if (m_iriParsing && ((result & (Check.DisplayCanonical | Check.EscapedCanonical | Check.BackslashInPath
-                                | Check.FoundNonAscii | Check.NotIriCanonical))
-                                == (Check.DisplayCanonical | Check.FoundNonAscii))){
-                        cF |= Flags.QueryIriCanonical;
-                    }
-
-                }
-            }
-            //
-            //Now we've got to parse the Fragment if any. Note that Fragment requires the presense of '#'
-            //
-            if (buildIriStringFromPath){
-                ushort offset = origIdx;
-
-                if (origIdx < m_originalUnicodeString.Length && m_originalUnicodeString[origIdx] == '#')
-                {
-                    ++origIdx; // This is to exclude first '#' character from checking
-                    FindEndOfComponent(m_originalUnicodeString, ref origIdx, (ushort)m_originalUnicodeString.Length, c_EOL);
-
-                    // Correctly escape unescape
-                    string escapedPath = EscapeUnescapeIri(m_originalUnicodeString, offset, origIdx, UriComponents.Fragment);
-
-                    // Normalize path
-                    try{
-                        if (UriParser.ShouldUseLegacyV2Quirks)
-                            m_String += escapedPath.Normalize(NormalizationForm.FormC);
-                        else
-                            m_String += escapedPath;
-                    }
-                    catch (ArgumentException){
-                        UriFormatException e = GetException(ParsingError.BadFormat);
-                        throw e;
-                    }
-
-                    if (!ServicePointManager.AllowAllUriEncodingExpansion && m_String.Length > ushort.MaxValue){
-                        UriFormatException e = GetException(ParsingError.SizeLimit);
-                        throw e;
-                    }
-
-                    length = (ushort)m_String.Length;
-                }
-            }
-
-            m_Info.Offset.Fragment = idx;
-
-            fixed (char* str = m_String){
-                if (idx < length && str[idx] == '#'){
-                    ++idx; // This is to exclude first '#' character from checking
-                    //We don't using c_DummyChar since want to allow '?' and '#' as unescaped
-                    result = CheckCanonical(str, ref idx, length, c_EOL);
-                    if ((result & Check.DisplayCanonical) == 0){
-                        cF |= Flags.FragmentNotCanonical;
-                    }
-
-                    if ((result & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical){
-                        cF |= Flags.E_FragmentNotCanonical;
-                    }
-
-                    if (m_iriParsing && ((result & (Check.DisplayCanonical | Check.EscapedCanonical | Check.BackslashInPath
-                                | Check.FoundNonAscii | Check.NotIriCanonical))
-                                == (Check.DisplayCanonical | Check.FoundNonAscii))){
-                        cF |= Flags.FragmentIriCanonical;
-                    }
-
-                }
-            }
-                m_Info.Offset.End = idx;
-        Done:
-
-            cF |= Flags.AllUriInfoSet;
-            lock (m_Info)
-            {
-                m_Flags |= cF;
-            }
-            m_Flags |= Flags.RestUnicodeNormalized;
-        }
-
-        //
-        //
-        // verifies the syntax of the scheme part
-        // Checks on implicit File: scheme due to simple Dos/Unc path passed
-        // returns the start of the next component  position
-        // throws UriFormatException if invalid scheme
-        //
-        unsafe static private ushort ParseSchemeCheckImplicitFile(char *uriString, ushort length, 
-            ref ParsingError err, ref Flags flags, ref UriParser syntax) {
-
-            ushort idx = 0;
-
-            //skip whitespaces
-            while(idx < length && IsLWS(uriString[idx])) {
-                ++idx;
-            }
-
-            // sets the recognizer for well known registered schemes
-            // file, ftp, http, https, uuid, etc
-            // Note that we don't support one-letter schemes that will be put into a DOS path bucket
-
-            // 
-            ushort end = idx;
-            while (end < length && uriString[end] != ':') {
-                ++end;
-            }
-
-            // NB: On 64-bits we will use less optimized code from CheckSchemeSyntax()
-            //
-            if (IntPtr.Size == 4) {
-                // long = 4chars: The minimal size of a known scheme is 2 + ':'
-                if (end != length && end >= idx+2 && 
-                    CheckKnownSchemes((long*) (uriString + idx), (ushort)(end-idx), ref syntax)) {
-                    return (ushort)(end+1);
-                }
-            }
-
-            //NB: A string must have at least 3 characters and at least 1 before ':'
-            if (idx+2 >= length || end == idx) {
-                err = ParsingError.BadFormat;
-                return 0;
-            }
-
-            //Check for supported special cases like a DOS file path OR a UNC share path
-            //NB: A string may not have ':' if this is a UNC path
-        {
-            char c;
-            if ((c=uriString[idx+1]) == ':' || c == '|') {
-#if !PLATFORM_UNIX
-                //DOS-like path?
-                if (IsAsciiLetter(uriString[idx])) {
-                    if((c=uriString[idx+2]) == '\\' || c== '/') {
-                        flags |= (Flags.DosPath|Flags.ImplicitFile|Flags.AuthorityFound);
-                        syntax = UriParser.FileUri;
-                        return idx;
-                    }
-                    err = ParsingError.MustRootedPath;
-                    return 0;
-                }
-#endif // !PLATFORM_UNIX
-                if (c == ':')
-                    err = ParsingError.BadScheme;
-                else
-                    err = ParsingError.BadFormat;
-                return 0;
-            }
-#if !PLATFORM_UNIX
-            else if ((c=uriString[idx]) == '/' || c == '\\') {
-                //UNC share ?
-                if ((c=uriString[idx+1]) == '\\' || c == '/') {
-                    flags |= (Flags.UncPath|Flags.ImplicitFile|Flags.AuthorityFound);
-                    syntax = UriParser.FileUri;
-                    idx+=2;
-                    // V1.1 compat this will simply eat any slashes prepended to a UNC path
-                    while (idx < length && ((c=uriString[idx]) == '/' ||  c == '\\'))
-                        ++idx;
-
-                    return idx;
-                }
-                err = ParsingError.BadFormat;
-                return 0;
-            }
-#else
-            else if (uriString[idx] == '/') {
-                // On UNIX an implicit file has the form /<path> or scheme:///<path>
-                if (idx == 0 || uriString[idx-1] != ':' ) {
-                    // No scheme present; implicit /<path> starting at idx
-                    flags |= (Flags.ImplicitFile|Flags.AuthorityFound);
-                    syntax = UriParser.FileUri;
-                    return idx;
-                } else if (uriString[idx+1] == '/' && uriString[idx+2] == '/') {
-                    // scheme present; rooted path starts at idx + 2
-                    flags |= (Flags.ImplicitFile|Flags.AuthorityFound);
-                    syntax = UriParser.FileUri;
-                    idx+=2;
-                    return idx;
-                }
-            }
-            else if (uriString[idx] == '\\') {
-                err = ParsingError.BadFormat;
-                return 0;
-            }
-#endif // !PLATFORM_UNIX
-        }
-
-            if (end == length) {
-                err = ParsingError.BadFormat;
-                return 0;
-            }
-
-            // Here could be a possibly valid, and not well-known scheme
-            // Finds the scheme delimiter
-            // we don;t work with the schemes names > c_MaxUriSchemeName (should be ~1k)
-            if ((end-idx) > c_MaxUriSchemeName) {
-                err = ParsingError.SchemeLimit;
-                return 0;
-            }
-
-            //Check the syntax, canonicalize  and avoid a GC call
-            char* schemePtr = stackalloc char[end-idx];
-            for (length = 0; idx < end; ++idx) {
-                schemePtr[length++] = uriString[idx];
-            }
-            err = CheckSchemeSyntax(schemePtr, length, ref syntax);
-            if (err != ParsingError.None) {
-                return 0;
-            }
-            return (ushort)(end+1);
-        }
-        //
-        // Quickly parses well known schemes.
-        // nChars does not include the last ':'. Assuming there is one at the end of passed buffer
-        unsafe static private bool CheckKnownSchemes(long *lptr, ushort nChars, ref UriParser syntax) {
-            //NOTE beware of too short input buffers!
-
-            const long _HTTP_Mask0   = 'h'|('t'<<16)|((long)'t'<<32)|((long)'p'<<48);
-            const char _HTTPS_Mask1  = 's';
-            const int  _WS_Mask      = 'w'|('s'<<16);
-            const long _WSS_Mask     = 'w'|('s'<<16)|((long)'s'<<32)|((long)':'<<48);
-            const long _FTP_Mask     = 'f'|('t'<<16)|((long)'p'<<32)|((long)':'<<48);
-            const long _FILE_Mask0   = 'f'|('i'<<16)|((long)'l'<<32)|((long)'e'<<48);
-            const long _GOPHER_Mask0 = 'g'|('o'<<16)|((long)'p'<<32)|((long)'h'<<48);
-            const int  _GOPHER_Mask1 = 'e'|('r'<<16);
-            const long _MAILTO_Mask0 = 'm'|('a'<<16)|((long)'i'<<32)|((long)'l'<<48);
-            const int  _MAILTO_Mask1 = 't'|('o'<<16);
-            const long _NEWS_Mask0   = 'n'|('e'<<16)|((long)'w'<<32)|((long)'s'<<48);
-            const long _NNTP_Mask0   = 'n'|('n'<<16)|((long)'t'<<32)|((long)'p'<<48);
-            const long _UUID_Mask0   = 'u'|('u'<<16)|((long)'i'<<32)|((long)'d'<<48);
-
-            const long _TELNET_Mask0 = 't'|('e'<<16)|((long)'l'<<32)|((long)'n'<<48);
-            const int  _TELNET_Mask1 = 'e'|('t'<<16);
-
-            const long _NETXXX_Mask0 = 'n'|('e'<<16)|((long)'t'<<32)|((long)'.'<<48);
-            const long _NETTCP_Mask1 = 't'|('c'<<16)|((long)'p'<<32)|((long)':'<<48);
-            const long _NETPIPE_Mask1 = 'p'|('i'<<16)|((long)'p'<<32)|((long)'e'<<48);
-
-            const long _LDAP_Mask0   = 'l'|('d'<<16)|((long)'a'<<32)|((long)'p'<<48);
-
-
-            const long _LOWERCASE_Mask = 0x0020002000200020L;
-            const int  _INT_LOWERCASE_Mask = 0x00200020;
-
-            if (nChars == 2) {
-                // This is the only known scheme of length 2
-                if ((((int)*lptr) | _INT_LOWERCASE_Mask) == _WS_Mask) {
-                    syntax = UriParser.WsUri;
-                    return true;
-                }
-                return false;
-            }
-
-            //Map to a known scheme if possible
-            //upgrade 4 letters to ASCII lower case, keep a false case to stay false
-            switch (*lptr | _LOWERCASE_Mask) {
-                case _HTTP_Mask0:
-                    if (nChars == 4) {
-                        syntax = UriParser.HttpUri;
-                        return true;
-                    }
-                    if (nChars == 5 && ((*(char*)(lptr+1))|0x20) == _HTTPS_Mask1) {
-                        syntax = UriParser.HttpsUri;
-                        return true;
-                    }
-                    break;
-                case _WSS_Mask:
-                    if (nChars == 3)
-                    {
-                        syntax = UriParser.WssUri;
-                        return true;
-                    }
-                    break;
-                case _FILE_Mask0:
-                    if (nChars == 4) {
-                        syntax = UriParser.FileUri;
-                        return true;
-                    }
-                    break;
-                case _FTP_Mask:
-                    if (nChars == 3) {
-                        syntax = UriParser.FtpUri;
-                        return true;
-                    }
-                    break;
-
-                case _NEWS_Mask0:
-                    if (nChars == 4) {
-                        syntax = UriParser.NewsUri;
-                        return true;
-                    }
-                    break;
-
-                case _NNTP_Mask0:
-                    if (nChars == 4) {
-                        syntax = UriParser.NntpUri;
-                        return true;
-                    }
-                    break;
-
-                case _UUID_Mask0:
-                    if (nChars == 4) {
-                        syntax = UriParser.UuidUri;
-                        return true;
-                    }
-                    break;
-
-                case _GOPHER_Mask0:
-                    if (nChars == 6 && (*(int*)(lptr+1)|_INT_LOWERCASE_Mask) == _GOPHER_Mask1) {
-                        syntax = UriParser.GopherUri;
-                        return true;
-                    }
-                    break;
-                case _MAILTO_Mask0:
-                    if (nChars == 6 && (*(int*)(lptr+1)|_INT_LOWERCASE_Mask) == _MAILTO_Mask1) {
-                        syntax = UriParser.MailToUri;
-                        return true;
-                    }
-                    break;
-
-                case _TELNET_Mask0:
-                    if (nChars == 6 && (*(int*)(lptr+1)|_INT_LOWERCASE_Mask) == _TELNET_Mask1) {
-                        syntax = UriParser.TelnetUri;
-                        return true;
-                    }
-                    break;
-
-                case _NETXXX_Mask0:
-                    if (nChars == 8 && (*(lptr+1)|_LOWERCASE_Mask) == _NETPIPE_Mask1) {
-                        syntax = UriParser.NetPipeUri;
-                        return true;
-                    }
-                    else if (nChars == 7 && (*(lptr+1)|_LOWERCASE_Mask) == _NETTCP_Mask1) {
-                        syntax = UriParser.NetTcpUri;
-                        return true;
-                    }
-                    break;
-
-                case _LDAP_Mask0:
-                    if (nChars == 4) {
-                        syntax = UriParser.LdapUri;
-                        return true;
-                    }
-                    break;
-                default:    break;
-            }
-            return false;
-        }
-
-        //
-        //
-        // This will check whether a scheme string follows the rules
-        //
-        unsafe static private ParsingError CheckSchemeSyntax(char* ptr, ushort length, ref UriParser syntax) {
-            //First character must be an alpha
-        {
-            char c = *ptr;
-            if (c >= 'a' && c <= 'z') {
-                ;
-            } else if (c >= 'A' && c <= 'Z') {
-                *ptr = (char)(c | 0x20);    //make it lowercase
-            } else {
-                return ParsingError.BadScheme;
-            }
-        }
-
-            for (ushort i = 1; i < length; ++i) {
-                char c = ptr[i];
-                if (c >= 'a' && c <= 'z') {
-                    ;
-                } else if (c >= 'A' && c <= 'Z') {
-                    ptr[i] = (char)(c | 0x20);    //make it lowercase
-                } else if (c >= '0' && c <= '9') {
-                    ;
-                } else if (c == '+' || c == '-' || c == '.') {
-                    ;
-                } else {
-                    return ParsingError.BadScheme;
-                }
-            }
-            // A not well-known scheme, needs string creation
-            // Note it is already in the lower case as required.
-            string str  =  new string(ptr, 0, length);
-            syntax = UriParser.FindOrFetchAsUnknownV1Syntax(str);
-            return ParsingError.None;
-        }
-        //
-        //
-        // Checks the syntax of an authority component. It may also get a userInfo if present
-        // Returns an error if no/mailformed authority found
-        // Does not NOT touch m_Info
-        // Returns position of the Path component
-        //
-        // Must be called in the ctor only
-        private unsafe ushort CheckAuthorityHelper( char* pString, ushort idx, ushort length,
-            ref ParsingError err, ref Flags flags, UriParser syntax, ref string newHost )
-        {
-            int end = length;
-            char ch;
-            int startInput = idx;
-            ushort start = idx;
-            newHost = null;
-            bool justNormalized = false;
-            bool iriParsing = (s_IriParsing && IriParsingStatic(syntax)); // perf
-            bool hasUnicode = ((flags & Flags.HasUnicode) != 0); // perf
-            bool hostNotUnicodeNormalized = ((flags & Flags.HostUnicodeNormalized) == 0); // perf
-            UriSyntaxFlags syntaxFlags = syntax.Flags;
-
-            // need to build new Iri'zed string
-            if (hasUnicode && iriParsing && hostNotUnicodeNormalized){
-                newHost = m_originalUnicodeString.Substring(0, startInput);
-            }
-
-            //Special case is an empty authority
-            if (idx == length || ((ch=pString[idx]) == '/' || (ch == '\\' && StaticIsFile(syntax)) || ch == '#' || ch == '?'))
-            {
-                if (syntax.InFact(UriSyntaxFlags.AllowEmptyHost))
-                {
-                    flags &= ~Flags.UncPath;    //UNC cannot have an empty hostname
-                    if (StaticInFact(flags, Flags.ImplicitFile))
-                        err = ParsingError.BadHostName;
-                    else
-                        flags |= Flags.BasicHostType;
-                }
-                else
-                    err = ParsingError.BadHostName;
-
-                if (hasUnicode && iriParsing && hostNotUnicodeNormalized){
-                    flags |= Flags.HostUnicodeNormalized;// no host
-                }
-
-                 return idx;
-            }
-
-//#if PLATFORM_UNIX
-//            if (StaticIsFile(syntax) && ch != '/') {
-//                // On UNIX a file URL may only have an empty authority
-//                err = ParsingError.NonEmptyHost;
-//                return idx;
+// //------------------------------------------------------------------------------
+// // <copyright file="URI.cs" company="Microsoft">
+// //     Copyright (c) Microsoft Corporation.  All rights reserved.
+// // </copyright>
+// //------------------------------------------------------------------------------
+//
+// namespace System {
+//     using System.Runtime.InteropServices;
+//     using System.Text;
+//     using System.Globalization;
+//     using System.Security;
+//     using System.ComponentModel;
+//     // Not in SL:
+//     using System.Configuration;
+//     using System.Security.Permissions;
+//     using System.Runtime.Serialization;
+//     using Microsoft.Win32;
+//     using System.Threading;
+//     using System.Diagnostics.CodeAnalysis;
+//     using System.Net;
+//     [Serializable]
+//     [TypeConverter(typeof(UriTypeConverter))]
+//     public partial class Uri : ISerializable {
+//
+//         public static readonly string UriSchemeFile = UriParser.FileUri.SchemeName;
+//         public static readonly string UriSchemeFtp = UriParser.FtpUri.SchemeName;
+//         public static readonly string UriSchemeGopher = UriParser.GopherUri.SchemeName;
+//         public static readonly string UriSchemeHttp = UriParser.HttpUri.SchemeName;
+//         public static readonly string UriSchemeHttps = UriParser.HttpsUri.SchemeName;
+//         internal static readonly string UriSchemeWs = UriParser.WsUri.SchemeName;
+//         internal static readonly string UriSchemeWss = UriParser.WssUri.SchemeName;
+//         public static readonly string UriSchemeMailto = UriParser.MailToUri.SchemeName;
+//         public static readonly string UriSchemeNews = UriParser.NewsUri.SchemeName;
+//         public static readonly string UriSchemeNntp = UriParser.NntpUri.SchemeName;
+//         public static readonly string UriSchemeNetTcp = UriParser.NetTcpUri.SchemeName;
+//         public static readonly string UriSchemeNetPipe = UriParser.NetPipeUri.SchemeName;
+//         public static readonly string SchemeDelimiter = "://";
+//
+//
+//         private const int c_Max16BitUtf8SequenceLength = 3+3+3+3; //each unicode byte takes 3 escaped chars
+//         internal const int c_MaxUriBufferSize = 0xFFF0;
+//         private const int c_MaxUriSchemeName = 1024;
+//
+//         // untouched user string unless string has unicode chars and iriparsing is enabled
+//         // or idn is on and we have unicode host or idn host
+//         // In that case, this string is normalized, stripped of bidi chars, and validated
+//         // with char limits
+//         private string      m_String;
+//
+//         // untouched user string if string has unicode with iri on or unicode/idn host with idn on
+//         private string      m_originalUnicodeString;
+//
+//         private UriParser m_Syntax;   // This is a whole Uri syntax, not only the scheme name
+//         // temporarily stores dnssafe host when we have unicode/idn host and idn is on
+//         private string m_DnsSafeHost = null;
+//
+//         [Flags]
+//         private enum Flags : ulong {
+//             Zero                = 0x00000000,
+//
+//             SchemeNotCanonical     = 0x1,
+//             UserNotCanonical       = 0x2,
+//             HostNotCanonical       = 0x4,
+//             PortNotCanonical       = 0x8,
+//             PathNotCanonical       = 0x10,
+//             QueryNotCanonical      = 0x20,
+//             FragmentNotCanonical   = 0x40,
+//             CannotDisplayCanonical = 0x7F,
+//
+//             E_UserNotCanonical      = 0x80,
+//             E_HostNotCanonical      = 0x100,
+//             E_PortNotCanonical      = 0x200,
+//             E_PathNotCanonical      = 0x400,
+//             E_QueryNotCanonical     = 0x800,
+//             E_FragmentNotCanonical  = 0x1000,
+//             E_CannotDisplayCanonical = 0x1F80,
+//
+//
+//             ShouldBeCompressed      = 0x2000,
+//             FirstSlashAbsent        = 0x4000,
+//             BackslashInPath         = 0x8000,
+//
+//             IndexMask           = 0x0000FFFF,
+//             HostTypeMask        = 0x00070000,
+//             HostNotParsed   = 0x00000000,
+//             IPv6HostType    = 0x00010000,
+//             IPv4HostType    = 0x00020000,
+//             DnsHostType     = 0x00030000,
+// #if !PLATFORM_UNIX
+//             UncHostType     = 0x00040000,
+// #endif // !PLATFORM_UNIX
+//             BasicHostType   = 0x00050000,
+//             UnusedHostType  = 0x00060000,
+//             UnknownHostType = 0x00070000,
+//
+//             UserEscaped         = 0x00080000,
+//             AuthorityFound      = 0x00100000,
+//             HasUserInfo         = 0x00200000,
+//             LoopbackHost        = 0x00400000,
+//             NotDefaultPort      = 0x00800000,
+//
+//             UserDrivenParsing   = 0x01000000,
+//             CanonicalDnsHost    = 0x02000000,
+//             ErrorOrParsingRecursion = 0x04000000,   // Used to signal a default parser error and alsoe to confirm Port 
+//                                                     // and Host values in case of a custom user Parser
+// #if !PLATFORM_UNIX
+//             DosPath             = 0x08000000,
+//             UncPath             = 0x10000000,
+// #endif // !PLATFORM_UNIX
+//             ImplicitFile        = 0x20000000,
+//             MinimalUriInfoSet   = 0x40000000,
+//             AllUriInfoSet       = unchecked(0x80000000),
+//             IdnHost             = 0x100000000,
+//             HasUnicode          = 0x200000000,
+//             HostUnicodeNormalized = 0x400000000,
+//             RestUnicodeNormalized = 0x800000000,
+//             UnicodeHost         = 0x1000000000,
+//             IntranetUri         = 0x2000000000,
+//             UseOrigUncdStrOffset= 0x4000000000,
+//             // Is this component Iri canonical
+//             UserIriCanonical =          0x8000000000,
+//             PathIriCanonical =          0x10000000000,
+//             QueryIriCanonical =         0x20000000000,
+//             FragmentIriCanonical =      0x40000000000,
+//             IriCanonical =              0x78000000000,
+//         }
+//
+//         private Flags       m_Flags;
+//         private UriInfo     m_Info;
+//
+//         private class UriInfo {
+//             public string   Host;
+//             public string   ScopeId;        //only IP v6 may need this
+//             public string   String;
+//             public Offset   Offset;
+//             public string   DnsSafeHost;    // stores dns safe host when idn is on and we have unicode or idn host
+//             public MoreInfo MoreInfo;       // Multi-threading: This field must be always accessed through a _local_ 
+//                                             // stack copy of m_Info.
+//         };
+//
+//         [StructLayout(LayoutKind.Sequential, Pack=1)]
+//         private struct Offset {
+//             public ushort  Scheme;
+//             public ushort  User;
+//             public ushort  Host;
+//             public ushort  PortValue;
+//             public ushort  Path;
+//             public ushort  Query;
+//             public ushort  Fragment;
+//             public ushort  End;
+//         };
+//
+//         private class MoreInfo {
+//             public string   Path;
+//             public string   Query;
+//             public string   Fragment;
+//             public string   AbsoluteUri;
+//             public int      Hash;
+//             public string   RemoteUrl;
+//         };
+//
+//         private bool IsImplicitFile {
+//             get {return (m_Flags & Flags.ImplicitFile) != 0;}
+//         }
+//
+//         private bool IsUncOrDosPath {
+// #if !PLATFORM_UNIX
+//             get {return (m_Flags & (Flags.UncPath|Flags.DosPath)) != 0;}
+// #else
+//             get {return false;}
+// #endif // !PLATFORM_UNIX
+//         }
+//
+//         private bool IsDosPath {
+// #if !PLATFORM_UNIX
+//             get {return (m_Flags & Flags.DosPath) != 0;}
+// #else
+//             get {return false;}
+// #endif // !PLATFORM_UNIX
+//         }
+//
+//         private bool IsUncPath {
+// #if !PLATFORM_UNIX
+//             get {return (m_Flags & Flags.UncPath) != 0;}
+// #else
+//             get {return false;}
+// #endif // !PLATFORM_UNIX
+//         }
+//
+//         private Flags HostType {
+//             get {return m_Flags & Flags.HostTypeMask;}
+//         }
+//
+//         private UriParser Syntax {
+//             get {
+//                 return m_Syntax;
+//             }
+//         }
+//
+//         private bool IsNotAbsoluteUri {
+//             get {return (object) m_Syntax == null;}
+//         }
+//
+//         //
+//         // Checks if Iri parsing is allowed by the syntax & by config
+//         //
+//         private bool m_iriParsing;
+//
+//         //
+//         // Statically checks if Iri parsing is allowed by the syntax & by config
+//         //
+//         internal static bool IriParsingStatic( UriParser syntax )
+//         {
+//             return (s_IriParsing && (((syntax != null) && syntax.InFact(UriSyntaxFlags.AllowIriParsing)) ||
+//                    (syntax == null)));
+//         }
+//
+//         //
+//         // Checks if Idn is allowed by the syntax & by config
+//         //
+//         private bool AllowIdn
+//         {
+//             get { return    ((m_Syntax != null) && ((m_Syntax.Flags & UriSyntaxFlags.AllowIdn) != 0) &&
+//                             ((s_IdnScope == UriIdnScope.All) || ((s_IdnScope == UriIdnScope.AllExceptIntranet)
+//                                                                                 && NotAny(Flags.IntranetUri)))); }
+//         }
+//
+//         //
+//         // Checks statically if Idn is allowed by the syntax & by config
+//         //
+//         private bool AllowIdnStatic(UriParser syntax, Flags flags)
+//         {
+//             return ((syntax != null) && ((syntax.Flags & UriSyntaxFlags.AllowIdn) != 0) &&
+//                    ((s_IdnScope == UriIdnScope.All) || ((s_IdnScope == UriIdnScope.AllExceptIntranet)
+//                                                                             && StaticNotAny(flags, Flags.IntranetUri))));
+//         }
+//
+//         //
+//         // check if the scheme + host are in intranet or not
+//         // Used to determine of we apply idn or not
+//         //
+//         private static volatile IInternetSecurityManager s_ManagerRef = null;
+//         private static object s_IntranetLock = new object();
+//
+//         private bool IsIntranet(string schemeHost)
+//         {
+//             bool error = false;
+//             int zone = -1;
+//             int E_FAIL = unchecked((int)0x80004005);
+//
+//             // MapUrlToZone call below fails on scheme length > 32 so we consider this
+//             // not be be intranet
+//             //
+//             if (m_Syntax.SchemeName.Length > 32)
+//                 return false;
+//
+//             if (s_ManagerRef == null){
+//                 lock (s_IntranetLock){
+//                     if(s_ManagerRef == null)
+//                     {
+// #if !FEATURE_PAL
+//                         // Go through CoCreateInstance as creating arbitary COM object is no longer supported in AppX scenario
+//                         Guid clsid = typeof(InternetSecurityManager).GUID;
+//                         Guid iid = typeof(IInternetSecurityManager).GUID;
+//
+//                         object managerRef;
+//                         UnsafeNclNativeMethods.CoCreateInstance(
+//                             ref clsid ,
+//                             IntPtr.Zero,
+//                             UnsafeNclNativeMethods.CLSCTX_SERVER,
+//                             ref iid,
+//                             out managerRef
+//                             );
+//                         s_ManagerRef = managerRef as IInternetSecurityManager;
+// #else
+//                         s_ManagerRef = (IInternetSecurityManager)new InternetSecurityManager();
+// #endif // !FEATURE_PAL                        
+//                     }
+//                 }
+//             }
+//
+//             try{
+//                 s_ManagerRef.MapUrlToZone(schemeHost.TrimStart(_WSchars), out zone, 0);
+//             }
+//             catch (COMException ex){
+//                 if (ex.ErrorCode == E_FAIL){    // E_FAIL
+//                     error = true;
+//                 }
+//             }
+//             // If s_ManagerRef was initilized on an STA thread then it cannot be accessed from other threads.
+//             // Visual Studio Unit Tests are the primary scenario for this.
+//             catch (InvalidComObjectException) {
+//                 error = true;
+//             }
+//
+//             if(zone == (int) SecurityZone.Intranet)
+//                 return true;
+//
+//             // Do dot check for intranet if zone is trusted or untrusted
+//             // since an intranet zone may be in these zones as well
+//             if ((zone == (int)SecurityZone.Trusted) ||
+//                 (zone == (int)SecurityZone.Untrusted) || error)
+//             {
+//                 // do dot check
+//                 for (int i = 0; i < schemeHost.Length; ++i)
+//                 {
+//                     if (schemeHost[i] == '.')
+//                         return false;
+//                 }
+//                 return true;
+//             }
+//             return false;
+//         }
+//
+//         internal bool UserDrivenParsing
+//         {
+//             get {
+//                 return (m_Flags & Flags.UserDrivenParsing) != 0;
+//             }
+//         }
+//         private void SetUserDrivenParsing()
+//         {
+//             // we use = here to clear all parsing flags for a uri that we think is invalid.
+//             m_Flags = Flags.UserDrivenParsing | (m_Flags & Flags.UserEscaped);
+//         }
+//
+//         private ushort SecuredPathIndex {
+//             get {
+//                 // This is one more trouble with a Dos Path.
+//                 // This property gets "safe" first path slash that is not the first if path = c:\
+//                 if (IsDosPath) {
+//                     char ch = m_String[m_Info.Offset.Path];
+//                     return (ushort)((ch == '/' || ch == '\\')? 3 :2);
+//                 }
+//                 return (ushort)0;
+//             }
+//         }
+//
+//         private bool NotAny(Flags flags) {
+//             return (m_Flags & flags) == 0;
+//         }
+//
+//         private bool InFact(Flags flags) {
+//             return (m_Flags & flags) != 0;
+//         }
+//
+//         private static bool StaticNotAny(Flags allFlags, Flags checkFlags) {
+//             return (allFlags & checkFlags) == 0;
+//         }
+//
+//         private static bool StaticInFact(Flags allFlags, Flags checkFlags) {
+//             return (allFlags & checkFlags) != 0;
+//         }
+//
+//         //
+//         //
+//         private UriInfo EnsureUriInfo() {
+//             Flags cF = m_Flags;
+//             if ((m_Flags & Flags.MinimalUriInfoSet) == 0) {
+//                 CreateUriInfo(cF);
+//             }
+//             return m_Info;
+//         }
+//         //
+//         //
+//         private void EnsureParseRemaining() {
+//             if ((m_Flags & Flags.AllUriInfoSet) == 0) {
+//                 ParseRemaining();
+//             }
+//         }
+//         //
+//         //
+//         private void EnsureHostString(bool allowDnsOptimization) {
+//             EnsureUriInfo();
+//             if ((object)m_Info.Host == null) {
+//                 if (allowDnsOptimization && InFact(Flags.CanonicalDnsHost)) {
+//                     /* Optimization for a canonical DNS name
+//                     *  ATTN: the host string won't be created,
+//                     *  Hence ALL m_Info.Host callers first call EnsureHostString(false)
+//                     *  For example IsLoopBack property is one of such callers.
+//                     */
+//                     return;
+//                 }
+//                 CreateHostString();
+//             }
+//         }
+//
+//         //
+//         // Uri(string)
+//         //
+//         //  We expect to create a Uri from a display name - e.g. that was typed by
+//         //  a user, or that was copied & pasted from a document. That is, we do not
+//         //  expect already encoded URI to be supplied.
+//         //
+//         public Uri(string uriString){
+//             if ((object)uriString == null)
+//                 throw new ArgumentNullException("uriString");
+//
+//             CreateThis(uriString, false, UriKind.Absolute);
+//         }
+//
+//
+//         //
+//         // Uri(string, bool)
+//         //
+//         //  Uri constructor. Assumes that input string is canonically escaped
+//         //
+//         [Obsolete("The constructor has been deprecated. Please use new Uri(string). The dontEscape parameter is deprecated and is always false. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         public Uri(string uriString, bool dontEscape) {
+//             if ((object)uriString == null)
+//                 throw new ArgumentNullException("uriString");
+//
+//             CreateThis(uriString, dontEscape, UriKind.Absolute);
+//         }
+//
+//         //
+//         // Uri(Uri, string, bool)
+//         //
+//         //  Uri combinatorial constructor. Do not perform character escaping if
+//         //  DontEscape is true
+//         //
+//         [Obsolete("The constructor has been deprecated. Please new Uri(Uri, string). The dontEscape parameter is deprecated and is always false. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         public Uri(Uri baseUri, string relativeUri, bool dontEscape){
+//             if ((object)baseUri == null)
+//                 throw new ArgumentNullException("baseUri");
+//
+//             if (!baseUri.IsAbsoluteUri)
+//                 throw new ArgumentOutOfRangeException("baseUri");
+//
+//             CreateUri(baseUri, relativeUri, dontEscape);
+//         }
+//
+//         //
+//         // Uri(string, UriKind);
+//         //
+//         public Uri(string uriString, UriKind uriKind)
+//         {
+//             if ((object)uriString == null)
+//                 throw new ArgumentNullException("uriString");
+//
+//             CreateThis(uriString, false, uriKind);
+//         }
+//
+//
+//         //
+//         // Uri(Uri, string)
+//         //
+//         //  Construct a new Uri from a base and relative URI. The relative URI may
+//         //  also be an absolute URI, in which case the resultant URI is constructed
+//         //  entirely from it
+//         //
+//         public Uri(Uri baseUri, string relativeUri){
+//             if ((object)baseUri == null)
+//                 throw new ArgumentNullException("baseUri");
+//
+//             if (!baseUri.IsAbsoluteUri)
+//                 throw new ArgumentOutOfRangeException("baseUri");
+//
+//             CreateUri(baseUri, relativeUri, false);
+//         }
+//
+//         private void CreateUri(Uri baseUri, string relativeUri, bool dontEscape)
+//         {
+//             // Parse relativeUri and populate Uri internal data.
+//             CreateThis(relativeUri, dontEscape, UriKind.RelativeOrAbsolute);
+//
+//             UriFormatException e;
+//             if (baseUri.Syntax.IsSimple)
+//             {
+//                 // Resolve Uris if possible OR get merged Uri String to re-parse below
+//                 Uri uriResult = ResolveHelper(baseUri, this, ref relativeUri, ref dontEscape, out e);
+//
+//                 if (e != null)
+//                     throw e;
+//
+//                 // If resolved into a Uri then we build from that Uri
+//                 if (uriResult != null)
+//                 {
+//                     if ((object)uriResult != (object)this)
+//                         CreateThisFromUri(uriResult);
+//
+//                     return;
+//                 }
+//             }
+//             else
+//             {
+//                 dontEscape = false;
+//                 relativeUri = baseUri.Syntax.InternalResolve(baseUri, this, out e);
+//                 if (e != null)
+//                     throw e;
+//             }
+//
+//             m_Flags = Flags.Zero;
+//             m_Info = null;
+//             m_Syntax = null;
+//             // If not resolved, we reparse modified Uri string and populate Uri internal data.
+//             CreateThis(relativeUri, dontEscape, UriKind.Absolute);
+//         }
+//
+//         //
+//         // Uri(Uri , Uri )
+//         // Note: a static Create() method should be used by users, not this .ctor
+//         //
+//         public Uri(Uri baseUri, Uri relativeUri)
+//         {
+//             if ((object)baseUri == null)
+//                 throw new ArgumentNullException("baseUri");
+//
+//             if (!baseUri.IsAbsoluteUri)
+//                 throw new ArgumentOutOfRangeException("baseUri");
+//
+//             CreateThisFromUri(relativeUri);
+//
+//             string newUriString = null;
+//             UriFormatException e;
+//             bool dontEscape;
+//
+//             if (baseUri.Syntax.IsSimple)
+//             {
+//                 dontEscape = InFact(Flags.UserEscaped);
+//                 relativeUri = ResolveHelper(baseUri, this, ref newUriString, ref dontEscape, out e);
+//
+//                 if (e != null)
+//                     throw e;
+//
+//                 if (relativeUri != null)
+//                 {
+//                     if ((object)relativeUri != (object)this)
+//                         CreateThisFromUri(relativeUri);
+//
+//                     return;
+//                 }
+//             }
+//             else
+//             {
+//                 dontEscape = false;
+//                 newUriString = baseUri.Syntax.InternalResolve(baseUri, this, out e);
+//                 if (e != null)
+//                     throw e;
+//             }
+//
+//             m_Flags = Flags.Zero;
+//             m_Info = null;
+//             m_Syntax = null;
+//             CreateThis(newUriString, dontEscape, UriKind.Absolute);
+//         }
+//
+//         //
+//         // This method is shared by base+relative Uris constructors and is only called from them.
+//         // The assumptions:
+//         //  - baseUri is a valid absolute Uri
+//         //  - relative part is not null and not empty
+//         private unsafe static ParsingError GetCombinedString(Uri baseUri, string relativeStr, 
+//             bool dontEscape, ref string result)
+//         {
+//             // NB: This is not RFC2396 compliant although it is inline with w3c.org recommendations
+//             // This parser will allow the relativeStr to be an absolute Uri with the different scheme
+//             // In fact this is strict violation of RFC2396
+//             //
+//             for (int i=0; i < relativeStr.Length; ++i)
+//             {
+//                 if (relativeStr[i] == '/' || relativeStr[i] == '\\' || relativeStr[i] == '?' || relativeStr[i] == '#')
+//                 {
+//                     break;
+//                 }
+//                 else if (relativeStr[i] == ':')
+//                 {
+//                     if (i < 2)
+//                     {
+//                         // Note we don't support one-letter Uri schemes.
+//                         // Hence anything like x:sdsd is a relative path and be added to the baseUri Path
+//                         break;
+//                     }
+//                     string scheme =  relativeStr.Substring(0, i);
+//                     fixed (char* sptr = scheme) {
+//                         UriParser syntax = null;
+//                         if (CheckSchemeSyntax(sptr, (ushort) scheme.Length, ref syntax) == ParsingError.None) {
+//                             if (baseUri.Syntax == syntax) {
+//                                 //Remove the scheme for backward Uri parsers compatibility
+//                                 if (i+1 < relativeStr.Length) {
+//                                     relativeStr = relativeStr.Substring(i+1);
+//                                 }
+//                                 else {
+//                                     relativeStr = string.Empty;
+//                                 }
+//                             }
+//                             else {
+//                                 // This is the place where we switch the scheme.
+//                                 // Return relative part as the result Uri.
+//                                 result = relativeStr;
+//                                 return ParsingError.None;
+//                             }
+//                         }
+//                     }
+//                     break;
+//                 }
+//             }
+//
+//             if (relativeStr.Length == 0) {
+//                 result = baseUri.OriginalString;
+//                 return ParsingError.None;
+//             }
+//
+//             result = CombineUri(baseUri, relativeStr, dontEscape? UriFormat.UriEscaped: UriFormat.SafeUnescaped);
+//             return ParsingError.None;
+//         }
+//         //
+//         private static UriFormatException GetException(ParsingError err)
+//         {
+//             switch (err)
+//             {
+//                 case ParsingError.None:
+//                     return null;
+//                 // Could be OK for Relative Uri
+//                 case ParsingError.BadFormat:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_BadFormat));
+//                 case ParsingError.BadScheme:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_BadScheme));
+//                 case ParsingError.BadAuthority:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_BadAuthority));
+//                 case ParsingError.EmptyUriString:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_EmptyUri));
+//                 // Fatal
+//                 case ParsingError.SchemeLimit:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_SchemeLimit));
+//                 case ParsingError.SizeLimit:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_SizeLimit));
+//                 case ParsingError.MustRootedPath:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_MustRootedPath));
+//                 // Derived class controllable
+//                 case ParsingError.BadHostName:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_BadHostName));
+//                 case ParsingError.NonEmptyHost: //unix-only
+//                     return new UriFormatException(SR.GetString(SR.net_uri_BadFormat));
+//                 case ParsingError.BadPort:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_BadPort));
+//                 case ParsingError.BadAuthorityTerminator:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_BadAuthorityTerminator));
+//                 case ParsingError.CannotCreateRelative:
+//                     return new UriFormatException(SR.GetString(SR.net_uri_CannotCreateRelative));
+//                 default:
+//                     break;
+//             }
+//             return new UriFormatException(SR.GetString(SR.net_uri_BadFormat));
+//         }
+//
+//         #region !Silverlight
+//
+//         //
+//         // ISerializable constructor
+//         //
+//         protected Uri(SerializationInfo serializationInfo, StreamingContext streamingContext)
+//         {
+//             string uriString = serializationInfo.GetString("AbsoluteUri");
+//
+//             if (uriString.Length != 0)
+//             {
+//                 CreateThis(uriString, false, UriKind.Absolute);
+//                 return;
+//             }
+//
+//             uriString = serializationInfo.GetString("RelativeUri");
+//             if ((object)uriString == null)
+//                 throw new ArgumentNullException("uriString");
+//
+//             CreateThis(uriString, false, UriKind.Relative);
+//         }
+//
+//         //
+//         // ISerializable method
+//         //
+//         /// <internalonly/>
+//         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
+//         [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter=true)]
+//         void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
+//         {
+//             GetObjectData(serializationInfo, streamingContext);
+//         }
+//
+//         //
+//         // FxCop: provide some way for derived classes to access GetObjectData even if the derived class
+//         // explicitly re-inherits ISerializable.
+//         //
+//         [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter=true)]
+//         protected void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
+//         {
+//
+//             if (IsAbsoluteUri)
+//                 serializationInfo.AddValue("AbsoluteUri", GetParts(UriComponents.SerializationInfoString, UriFormat.UriEscaped));
+//             else
+//             {
+//                 serializationInfo.AddValue("AbsoluteUri", string.Empty);
+//                 serializationInfo.AddValue("RelativeUri", GetParts(UriComponents.SerializationInfoString, UriFormat.UriEscaped));
+//             }
+//         }
+//
+//         #endregion !Silverlight
+//
+//         //
+//         //
+//         //
+//         public string AbsolutePath {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 string path = PrivateAbsolutePath;
+//                 //
+//                 // 
+//
+//
+//                 if (IsDosPath && path[0] == '/') {
+//                     path =  path.Substring(1);
+//                 }
+//                 return path;
+//             }
+//         }
+//         //
+//         private string PrivateAbsolutePath {
+//             get {
+//                 UriInfo info = EnsureUriInfo();
+//                 if ((object) info.MoreInfo == null) {
+//                     info.MoreInfo = new MoreInfo();
+//                 }
+//                 string result = info.MoreInfo.Path;
+//                 if ((object) result == null) {
+//                     result = GetParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
+//                     info.MoreInfo.Path = result;
+//                 }
+//                 return result;
+//             }
+//         }
+//
+//         //
+//         //
+//         //
+//         public string AbsoluteUri {
+//             get {
+//                 if (m_Syntax == null){
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 UriInfo info = EnsureUriInfo();
+//                 if ((object) info.MoreInfo == null) {
+//                     info.MoreInfo = new MoreInfo();
+//                 }
+//                 string result = info.MoreInfo.AbsoluteUri;
+//                 if ((object) result == null) {
+//                     result = GetParts(UriComponents.AbsoluteUri, UriFormat.UriEscaped);
+//                     info.MoreInfo.AbsoluteUri = result;
+//                 }
+//                 return result;
+//             }
+//         }
+//
+//         //
+//         // LocalPath
+//         //
+//         //  Returns a 'local' version of the path. This is mainly for file: URI
+//         //  such that DOS and UNC paths are returned with '/' converted back to
+//         //  '\', and any escape sequences converted
+//         //
+//         //  The form of the returned path is in NOT Escaped
+//         //
+//         public string LocalPath {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//                 return GetLocalPath();
+//             }
+//         }
+//
+//         #region !Silverlight
+//         //
+//         //
+//         // The result is of the form "hostname[:port]" Port is omitted if default
+//         //
+//         public string Authority {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 // 
+//                 return GetParts(UriComponents.Host | UriComponents.Port, UriFormat.UriEscaped);
+//             }
+//         }
+//         //
+//         //
+//         public UriHostNameType HostNameType {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 if (m_Syntax.IsSimple)
+//                     EnsureUriInfo();
+//                 else
+//                 {
+//                     // For a custom parser we request HostString creation to confirm HostType
+//                     EnsureHostString(false);
+//                 }
+//
+//                 switch (HostType) {
+//                     case Flags.DnsHostType:   return UriHostNameType.Dns;
+//                     case Flags.IPv4HostType:  return UriHostNameType.IPv4;
+//                     case Flags.IPv6HostType:  return UriHostNameType.IPv6;
+//                     case Flags.BasicHostType: return UriHostNameType.Basic;
+// #if !PLATFORM_UNIX
+//                     case Flags.UncHostType:   return UriHostNameType.Basic; //return (UriHostNameType)(UriHostNameType.Basic+10);
+// #endif // !PLATFORM_UNIX
+//                     case Flags.UnknownHostType: return UriHostNameType.Unknown;
+//                     default:
+//                         break;
+//                 }
+//                 return UriHostNameType.Unknown;
+//             }
+//         }
+//         //
+//         //
+//         public bool IsDefaultPort {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//                 if (m_Syntax.IsSimple)
+//                     EnsureUriInfo();
+//                 else
+//                 {
+//                     // For a custom parser we request HostString creation that will aso set the port
+//                     EnsureHostString(false);
+//                 }
+//
+//                 return NotAny(Flags.NotDefaultPort);
+//             }
+//         }
+//         //
+//         //
+//         public bool IsFile {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 return (object)m_Syntax.SchemeName == (object)UriSchemeFile;
+//             }
+//         }
+//         //
+//         //
+//         public bool IsLoopback {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 EnsureHostString(false);
+//
+//                 return InFact(Flags.LoopbackHost);
+//             }
+//         }
+//
+//         //
+//         //
+//         //  Gets the escaped Uri.AbsolutePath and Uri.Query
+//         //  properties separated by a "?" character.
+//         public string PathAndQuery {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 string result = GetParts(UriComponents.PathAndQuery, UriFormat.UriEscaped);
+//                 //
+//                 // 
+//
+//
+//                 if (IsDosPath && result[0] == '/') {
+//                     result = result.Substring(1);
+//                 }
+//                 return result;
+//             }
+//         }
+//
+//         //
+//         //
+//         //  Gets an array of the segments that make up a URI.
+//         public string[] Segments {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 string[] segments = null; // used to be a class cached result
+//                 if (segments == null) {
+//
+//                     string path = PrivateAbsolutePath;
+//
+//                     if (path.Length == 0) {
+//                         segments = new string[0];
+//                     }
+//                     else {
+//                         System.Collections.ArrayList pathSegments = new System.Collections.ArrayList();
+//                         int current = 0;
+//                         while (current < path.Length) {
+//                             int next = path.IndexOf('/', current);
+//                             if (next == -1) {
+//                                 next = path.Length - 1;
+//                             }
+//                             pathSegments.Add(path.Substring(current, (next - current) + 1));
+//                             current = next + 1;
+//                         }
+//                         segments = (string[])(pathSegments.ToArray(typeof(string)));
+//                     }
+//                 }
+//                 return segments;
+//             }
+//         }
+//
+//         #endregion !Silverlight
+//
+//         //
+//         //
+//         public bool IsUnc {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//                 return IsUncPath;
+//             }
+//         }
+//         
+//         //
+//         // Gets a hostname part (special formatting for IPv6 form)
+//         public string Host {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 return GetParts(UriComponents.Host, UriFormat.UriEscaped);
+//             }
+//         }
+//         
+//         private static bool StaticIsFile(UriParser syntax)
+//         {
+//             return syntax.InFact(UriSyntaxFlags.FileLikeUri);
+//         }
+//
+//         private static volatile bool s_ConfigInitialized; // Have the config values been initalized from config file
+//         private static volatile bool s_ConfigInitializing; // used for recursion detection while init. config values
+//
+//         // Value from config Uri section
+//         // The use of this IDN mechanic is discouraged on Win8+ due to native platform improvements.
+//         private static volatile UriIdnScope s_IdnScope = IdnElement.EnabledDefaultValue;
+//
+//         // Value from config Uri section
+//         // On by default in .NET 4.5+ and cannot be disabled by config.
+//         private static volatile bool s_IriParsing = 
+//             (UriParser.ShouldUseLegacyV2Quirks ? IriParsingElement.EnabledDefaultValue : true);
+//
+//         private static object s_initLock;
+//
+//         private static object InitializeLock {
+//             get {
+//                 if (s_initLock == null) {
+//                     object o = new object();
+//                     Interlocked.CompareExchange(ref s_initLock, o, null);
+//                 }
+//                 return s_initLock;
+//             }
+//         }
+//
+//         //
+//         // Reads values from config uri section
+//         //
+//         // This method is called if:
+//         // - a Uri is constructed, we parse the string and we find '%', >127 chars, or 'xn--'
+//         // - we parse the host and figure out if it is an IPv6 address
+//         private static void InitializeUriConfig()
+//         {
+//             if (!s_ConfigInitialized) {
+//                 lock(InitializeLock) {
+//                     if (!s_ConfigInitialized && !s_ConfigInitializing) {
+//
+//                         // setting s_ConfigInitializing to true makes sure, that in web scenarios,
+//                         // where Uri instances may be created while parsing the web.config files, will not
+//                         // call into this code block again. We'll enter the following code only once per
+//                         // AppDomain.
+//                         s_ConfigInitializing = true;
+//                         UriSectionInternal section = UriSectionInternal.GetSection();
+//
+//                         if (section != null) {
+//                             s_IdnScope = section.IdnScope;
+//                             // Iri can no longer be altered by the config, it is always on.
+//                             if (UriParser.ShouldUseLegacyV2Quirks) {
+//                                 s_IriParsing = section.IriParsing;
+//                             }
+//
+//                             SetEscapedDotSlashSettings(section, "http");
+//                             SetEscapedDotSlashSettings(section, "https");
+//                             SetEscapedDotSlashSettings(section, Uri.UriSchemeWs);
+//                             SetEscapedDotSlashSettings(section, Uri.UriSchemeWss);
+//                         }
+//
+//                         s_ConfigInitialized = true;
+//                         s_ConfigInitializing = false;
+//                     }
+//                 }
+//             }
+//         }
+//
+//         // Legacy - This no longer has any affect in .NET 4.5 (non-quirks). See UriParser.HttpSyntaxFlags.
+//         private static void SetEscapedDotSlashSettings(UriSectionInternal uriSection, string scheme)
+//         {
+//             // Currently we only support setting DontUnescapePathDotsAndSlashes for HTTP and HTTPS schemes.
+//             // We ignore all other values. We won't throw for two reasons:
+//             // - backward compatibility: Uri didn't throw so far.
+//             // - the config section gets only read if we actually find e.g. a %-character in the Uri. If not, this
+//             //   code never gets executed, resulting in a weird behavior for the customer: If one application run
+//             //   doesn't use Uris with %-characters, it doesn't throw, if another run uses %-characters it throws.
+//             //   => If we want to throw we have to rethink the current implementation.
+//             SchemeSettingInternal schemeSetting = uriSection.GetSchemeSetting(scheme);
+//             if (schemeSetting != null) {
+//                 // We check for equality, not if Options contains DontUnescapePathDotsAndSlashes:
+//                 // Currently we only support this flag. If more than this flag are set, then it is an invalid
+//                 // setting and we ignore it.
+//                 if (schemeSetting.Options == GenericUriParserOptions.DontUnescapePathDotsAndSlashes) {
+//                     UriParser parser = UriParser.GetSyntax(scheme);
+//                     parser.SetUpdatableFlags(UriSyntaxFlags.None);
+//                 }
+//             }
+//         }
+//
+//         private string GetLocalPath(){
+//             EnsureParseRemaining();
+//
+//             //Other cases will get a Unix-style path
+//             if (IsUncOrDosPath)
+//             {
+//                 EnsureHostString(false);
+//                 int start;
+//
+//                 // Do we have a valid local path right in m_string?
+//                 if (NotAny(Flags.HostNotCanonical|Flags.PathNotCanonical|Flags.ShouldBeCompressed)) {
+//
+//                     start = IsUncPath? m_Info.Offset.Host-2 :m_Info.Offset.Path;
+//
+//                     string str = (IsImplicitFile && m_Info.Offset.Host == (IsDosPath ? 0 : 2) && 
+//                         m_Info.Offset.Query == m_Info.Offset.End)
+//                             ? m_String
+//                             : (IsDosPath && (m_String[start] == '/' || m_String[start] == '\\'))
+//                                 ? m_String.Substring(start + 1, m_Info.Offset.Query - start - 1)
+//                                 : m_String.Substring(start, m_Info.Offset.Query - start);
+//
+//                     // Should be a rare case, convert c|\ into c:\
+//                     if (IsDosPath && str[1] == '|') {
+//                         // Sadly, today there is no method for replacong just one occurrence
+//                         str = str.Remove(1, 1);
+//                         str = str.Insert(1, ":");
+//                     }
+//
+//                     // check for all back slashes (though may be string.Replace is smart?)
+//                     for (int i = 0; i < str.Length; ++i) {
+//                         if (str[i] == '/') {
+//                             str = str.Replace('/', '\\');
+//                             break;
+//                         }
+//                     }
+//
+//                     return str;
+//                 }
+//
+//                 // Not everything went well, trying harder
+//
+//                 char[] result;
+//                 int count = 0;
+//                 start = m_Info.Offset.Path;
+//
+//                 string host = m_Info.Host;
+//                 result = new char [host.Length + 3 + m_Info.Offset.Fragment - m_Info.Offset.Path ];
+//
+//                 if (IsUncPath)
+//                 {
+//                     result[0] = '\\';
+//                     result[1] = '\\';
+//                     count = 2;
+//
+//                     UriHelper.UnescapeString(host, 0, host.Length, result, ref count, c_DummyChar, c_DummyChar, 
+//                         c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, false);
+//
+//                 }
+//                 else {
+//                     // Dos path
+//                     if(m_String[start] == '/' ||  m_String[start] == '\\') {
+//                         // Skip leading slash for a DOS path
+//                         ++start;
+//                     }
+//                 }
+//
+//
+//                 ushort pathStart = (ushort)count; //save for optional Compress() call
+//
+//                 UnescapeMode mode = (InFact(Flags.PathNotCanonical) && !IsImplicitFile) 
+//                     ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll): UnescapeMode.CopyOnly;
+//                 UriHelper.UnescapeString(m_String, start, m_Info.Offset.Query, result, ref count, c_DummyChar, 
+//                     c_DummyChar, c_DummyChar, mode, m_Syntax, true);
+//
+//                 // Possibly convert c|\ into c:\
+//                 if (result[1] == '|')
+//                     result[1] = ':';
+//
+//                 if (InFact(Flags.ShouldBeCompressed)) {
+//                     // suspecting not compressed path
+//                     // For a dos path we won't compress the "x:" part if found /../ sequences
+//                     result = Compress(result, (ushort)(IsDosPath? pathStart + 2: pathStart), ref count, m_Syntax);
+//                 }
+//
+//                 // We don't know whether all slashes were the back ones
+//                 // Plus going through Compress will turn them into / anyway
+//                 // Converting / back into \
+//                 for (ushort i = 0; i < (ushort) count; ++i) {
+//                     if (result[i] == '/') {
+//                         result[i] = '\\';
+//                     }
+//                 }
+//
+//                 return new string(result, 0, count);
+//
+//             }
+//             else {
+//                 // Return unescaped canonical path
+//                 // Note we cannot call GetParts here because it has circular dependancy on GelLocalPath method
+//                 return GetUnescapedParts(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.Unescaped);
+//             }
+//         }
+//
+//         //
+//         //
+//         //
+//         //
+//         public int Port {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 if (m_Syntax.IsSimple)
+//                     EnsureUriInfo();
+//                 else
+//                 {
+//                     // For a custom parser we request HostString creation that will aso set the port
+//                     EnsureHostString(false);
+//                 }
+//
+//                 if (InFact(Flags.NotDefaultPort)) {
+//                     return (int)m_Info.Offset.PortValue;
+//                 }
+//                 return m_Syntax.DefaultPort;
+//             }
+//         }
+//         //
+//         //
+//         //
+//         //  Gets the escaped query.
+//         public string Query {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 UriInfo info = EnsureUriInfo();
+//                 if ((object)info.MoreInfo == null) {
+//                     info.MoreInfo = new MoreInfo();
+//                 }
+//                 string result = info.MoreInfo.Query;
+//                 if ((object)result == null) {
+//                     result = GetParts(UriComponents.Query | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
+//                     info.MoreInfo.Query = result;
+//                 }
+//                 return result;
+//             }
+//         }
+//         //
+//         //
+//         //
+//         //    Gets the escaped fragment.
+//         public string Fragment {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 UriInfo info = EnsureUriInfo();
+//                 if ((object)info.MoreInfo == null) {
+//                     info.MoreInfo = new MoreInfo();
+//                 }
+//                 string result = info.MoreInfo.Fragment;
+//                 if ((object)result == null) {
+//                     result = GetParts(UriComponents.Fragment | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
+//                     info.MoreInfo.Fragment = result;
+//                 }
+//                 return result;
+//             }
+//         }
+//
+//         //
+//         //  Gets the Scheme string of this Uri
+//         //
+//         //
+//         public string Scheme {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 return m_Syntax.SchemeName;
+//             }
+//         }
+//
+//         //
+//         //  Was the original string switched from m_String to m_OriginalUnicodeString
+//         //  Will happen when Iri is turned on and we have unicode chars or of idn is
+//         //  is on and we have an idn or unicode host.
+//         //
+//         private bool OriginalStringSwitched
+//         {
+//             get{return ((m_iriParsing && InFact(Flags.HasUnicode)) ||
+//                         (AllowIdn && (InFact(Flags.IdnHost) || InFact(Flags.UnicodeHost))));}
+//         }
+//         //
+//         //    Gets the exact string passed by a user.
+//         public String OriginalString {
+//             get {
+//                 return OriginalStringSwitched ? m_originalUnicodeString : m_String;
+//             }
+//         }
+//
+//         //
+//         //    Gets the host string that is unescaped and if it's Ipv6 host,
+//         //    then the returned string is suitable for DNS lookup.
+//         //
+//         //    For Ipv6 this will strip [] and add ScopeId if was found in the original string
+//         public string DnsSafeHost {
+//             get {
+//
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 if (AllowIdn && (((m_Flags & Flags.IdnHost) != 0) || ((m_Flags & Flags.UnicodeHost) != 0))){
+//                     // return pre generated idn
+//                     EnsureUriInfo();
+//                     return m_Info.DnsSafeHost;
+//                 }
+//
+//                 EnsureHostString(false);
+//
+//                 if (!String.IsNullOrEmpty(m_Info.DnsSafeHost)) {
+//                     // Cached
+//                     return m_Info.DnsSafeHost;
+//                 } else if (m_Info.Host.Length == 0) {
+//                     // Empty host, no possible processing
+//                     return String.Empty;
+//                 }
+//
+//                 // Special case, will include ScopeID and strip [] around IPv6
+//                 // This will also unescape the host string
+//                 string ret = m_Info.Host;
+//
+//                 if (HostType == Flags.IPv6HostType) {
+//                     ret = ret.Substring(1, ret.Length - 2);
+//                     if ((object)m_Info.ScopeId != null) {
+//                         ret += m_Info.ScopeId;
+//                     }
+//                 }
+//                 // Validate that this basic host qualifies as Dns safe,
+//                 // It has looser parsing rules that might allow otherwise.
+//                 // It might be a registry-based host from RFC 2396 Section 3.2.1
+//                 else if (HostType == Flags.BasicHostType 
+//                     && InFact(Flags.HostNotCanonical | Flags.E_HostNotCanonical)) {
+//                     // Unescape everything
+//                     char[] dest = new char[ret.Length];
+//                     int count = 0;
+//                     UriHelper.UnescapeString(ret, 0, ret.Length, dest, ref count, c_DummyChar, c_DummyChar, 
+//                         c_DummyChar, UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, false);
+//                     ret = new string(dest, 0, count);
+//                 }
+//
+//                 m_Info.DnsSafeHost = ret;
+//
+//                 return ret;
+//             }
+//         }
+//
+//         // Returns the host name represented as IDN (using punycode encoding) regardless of app.config settings
+//         public string IdnHost {
+//             get {
+//                 string host = this.DnsSafeHost;
+//
+//                 if (HostType == Flags.DnsHostType) {
+//                     host = DomainNameHelper.IdnEquivalent(host);
+//                 }
+//
+//                 return host;
+//             }
+//         }
+//
+//         //
+//         //  Returns false if the string passed in the constructor cannot be parsed as
+//         //  valid AbsoluteUri. This could be a relative Uri instead.
+//         //
+//         public bool IsAbsoluteUri {
+//             get {
+//                 return m_Syntax != null;
+//             }
+//         }
+//         //
+//         //
+//         //  Returns 'true' if the 'dontEscape' parameter was set to 'true ' when the Uri instance was created.
+//         public bool UserEscaped {
+//             get {
+//                 return InFact(Flags.UserEscaped);
+//             }
+//         }
+//         //
+//         //
+//         //  Gets the user name, password, and other user specific information associated
+//         //  with the Uniform Resource Identifier (URI).
+//         public string UserInfo {
+//             get {
+//                 if (IsNotAbsoluteUri) {
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//                 }
+//
+//                 return GetParts(UriComponents.UserInfo, UriFormat.UriEscaped);
+//             }
+//         }
+//
+//         #region !Silverlight
+//
+//         //
+//         // CheckHostName
+//         //
+//         //  Determines whether a host name authority is a valid Host name according
+//         //  to DNS naming rules and IPv4 canonicalization rules
+//         //
+//         // Returns:
+//         //  true if <name> is valid else false
+//         //
+//         // Throws:
+//         //  Nothing
+//         //
+//         public static UriHostNameType CheckHostName(string name) {
+//
+//             if ((object)name == null || name.Length == 0 || name.Length > short.MaxValue) {
+//                 return UriHostNameType.Unknown;
+//             }
+//             int end = name.Length;
+//             unsafe {
+//                 fixed (char* fixedName = name) {
+//
+//                     if (name[0] == '[' && name[name.Length-1] == ']') {
+//                         // we require that _entire_ name is recognized as ipv6 address
+//                         if (IPv6AddressHelper.IsValid(fixedName, 1, ref end) && end == name.Length) {
+//                             return UriHostNameType.IPv6;
+//                         }
+//                     }
+//                     end = name.Length;
+//                     if (IPv4AddressHelper.IsValid(fixedName, 0 , ref end, false, false, false) && end == name.Length) {
+//                         return UriHostNameType.IPv4;
+//                     }
+//                     end = name.Length;
+//                     bool dummyBool = false;
+//                     if (DomainNameHelper.IsValid(fixedName, 0, ref end, ref dummyBool, false) && end == name.Length) {
+//                         return UriHostNameType.Dns;
+//                     }
+//
+//                     end = name.Length;
+//                     dummyBool = false;
+//                     if (DomainNameHelper.IsValidByIri(fixedName, 0, ref end, ref dummyBool, false) 
+//                         && end == name.Length) {
+//                         return UriHostNameType.Dns;
+//                     }
+//                 }
+//
+//                 //This checks the form without []
+//                 end = name.Length+2;
+//                 // we require that _entire_ name is recognized as ipv6 address
+//                 name = "["+name+"]";
+//                 fixed (char* newFixedName = name) {
+//                     if (IPv6AddressHelper.IsValid(newFixedName, 1, ref end) && end == name.Length) {
+//                         return UriHostNameType.IPv6;
+//                     }
+//                 }
+//             }
+//             return UriHostNameType.Unknown;
+//         }
+//
+//         //
+//         // GetLeftPart
+//         //
+//         //  Returns part of the URI based on the parameters:
+//         //
+//         // Inputs:
+//         //  <argument>  part
+//         //      Which part of the URI to return
+//         //
+//         // Returns:
+//         //  The requested substring
+//         //
+//         // Throws:
+//         //  UriFormatException if URI type doesn't have host-port or authority parts
+//         //
+//         public string GetLeftPart(UriPartial part) {
+//             if (IsNotAbsoluteUri) {
+//                 throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//             }
+//
+//             EnsureUriInfo();
+//             const UriComponents NonPathPart = (UriComponents.Scheme | UriComponents.UserInfo | UriComponents.Host | UriComponents.Port);
+//
+//             switch (part) {
+//                 case UriPartial.Scheme:
+//
+//                     return GetParts(UriComponents.Scheme | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
+//
+//                 case UriPartial.Authority:
+//
+//                     if (NotAny(Flags.AuthorityFound) || IsDosPath) {
+//
+//                         // 
+//
+//
+//
+//                         // From V1.0 comments:
+//
+//                         // anything that didn't have "//" after the scheme name
+//                         // (mailto: and news: e.g.) doesn't have an authority
+//                         //
+//
+//                         return String.Empty;
+//                     }
+//                     return GetParts(NonPathPart, UriFormat.UriEscaped);
+//
+//                 case UriPartial.Path:
+//                     return GetParts(NonPathPart | UriComponents.Path, UriFormat.UriEscaped);
+//
+//                 case UriPartial.Query:
+//                     return GetParts(NonPathPart | UriComponents.Path | UriComponents.Query, UriFormat.UriEscaped);
+//
+//             }
+//             throw new ArgumentException("part");
+//         }
+//
+//         //
+//         //
+//         /// Transforms a character into its hexadecimal representation.
+//         public static string HexEscape(char character) {
+//             if (character > '\xff') {
+//                 throw new ArgumentOutOfRangeException("character");
+//             }
+//             char[] chars = new char[3];
+//             int pos = 0;
+//             UriHelper.EscapeAsciiChar(character, chars, ref pos);
+//             return new string(chars);
+//         }
+//
+//         //
+//         // HexUnescape
+//         //
+//         //  Converts a substring of the form "%XX" to the single character represented
+//         //  by the hexadecimal value XX. If the substring s[Index] does not conform to
+//         //  the hex encoding format then the character at s[Index] is returned
+//         //
+//         // Inputs:
+//         //  <argument>  pattern
+//         //      String from which to read the hexadecimal encoded substring
+//         //
+//         //  <argument>  index
+//         //      Offset within <pattern> from which to start reading the hexadecimal
+//         //      encoded substring
+//         //
+//         // Outputs:
+//         //  <argument>  index
+//         //      Incremented to the next character position within the string. This
+//         //      may be EOS if this was the last character/encoding within <pattern>
+//         //
+//         // Returns:
+//         //  Either the converted character if <pattern>[<index>] was hex encoded, or
+//         //  the character at <pattern>[<index>]
+//         //
+//         // Throws:
+//         //  ArgumentOutOfRangeException
+//         //
+//
+//         public static char HexUnescape(string pattern, ref int index) {
+//             if ((index < 0) || (index >= pattern.Length)) {
+//                 throw new ArgumentOutOfRangeException("index");
+//             }
+//             if ((pattern[index] == '%')
+//                 && (pattern.Length - index >= 3)) {
+//                 char ret = UriHelper.EscapedAscii(pattern[index + 1], pattern[index + 2]);
+//                 if (ret != c_DummyChar) {
+//                     index += 3;
+//                     return ret;
+//                 }
+//             }
+//             return pattern[index++];
+//         }
+//
+//         //
+//         // IsHexEncoding
+//         //
+//         //  Determines whether a substring has the URI hex encoding format of '%'
+//         //  followed by 2 hexadecimal characters
+//         //
+//         // Inputs:
+//         //  <argument>  pattern
+//         //      String to check
+//         //
+//         //  <argument>  index
+//         //      Offset in <pattern> at which to check substring for hex encoding
+//         //
+//         // Assumes:
+//         //  0 <= <index> < <pattern>.Length
+//         //
+//         // Returns:
+//         //  true if <pattern>[<index>] is hex encoded, else false
+//         //
+//         // Throws:
+//         //  Nothing
+//         //
+//         public static bool IsHexEncoding(string pattern, int index) {
+//             if ((pattern.Length - index) < 3) {
+//                 return false;
+//             }
+//             if ((pattern[index] == '%') && UriHelper.EscapedAscii(pattern[index + 1], pattern[index + 2]) != c_DummyChar) {
+//                 return true;
+//             }
+//             return false;
+//         }
+//
+//         //
+//         // Is this a gen delim char from RFC 3986
+//         //
+//         internal static bool IsGenDelim(char ch)
+//         {
+//             return (ch == ':' || ch == '/' || ch == '?' || ch == '#' || ch == '[' || ch == ']' || ch == '@');
+//         }
+//
+//         #endregion !Silverlight
+//
+//         //
+//         // CheckSchemeName
+//         //
+//         //  Determines whether a string is a valid scheme name according to RFC 2396.
+//         //  Syntax is:
+//         //      scheme = alpha *(alpha | digit | '+' | '-' | '.')
+//         //
+//         public static bool CheckSchemeName(string schemeName) {
+//             if (((object)schemeName == null)
+//                 || (schemeName.Length == 0)
+//                 || !IsAsciiLetter(schemeName[0])) {
+//                 return false;
+//             }
+//             for (int i = schemeName.Length - 1; i > 0; --i) {
+//                 if (!(IsAsciiLetterOrDigit(schemeName[i])
+//                     || (schemeName[i] == '+')
+//                     || (schemeName[i] == '-')
+//                     || (schemeName[i] == '.'))) {
+//                     return false;
+//                 }
+//             }
+//             return true;
+//         }
+//
+//         //
+//         // IsHexDigit
+//         //
+//         //  Determines whether a character is a valid hexadecimal digit in the range
+//         //  [0..9] | [A..F] | [a..f]
+//         //
+//         // Inputs:
+//         //  <argument>  character
+//         //      Character to test
+//         //
+//         // Returns:
+//         //  true if <character> is a hexadecimal digit character
+//         //
+//         // Throws:
+//         //  Nothing
+//         //
+//         public static bool IsHexDigit(char character) {
+//             return ((character >= '0') && (character <= '9'))
+//                 || ((character >= 'A') && (character <= 'F'))
+//                 || ((character >= 'a') && (character <= 'f'));
+//         }
+//
+//         //
+//         // Returns:
+//         //  Number in the range 0..15
+//         //
+//         // Throws:
+//         //  ArgumentException
+//         //
+//         public static int FromHex(char digit) {
+//             if (((digit >= '0') && (digit <= '9'))
+//                 || ((digit >= 'A') && (digit <= 'F'))
+//                 || ((digit >= 'a') && (digit <= 'f'))) {
+//                 return  (digit <= '9')
+//                     ? ((int)digit - (int)'0')
+//                     : (((digit <= 'F')
+//                     ? ((int)digit - (int)'A')
+//                     : ((int)digit - (int)'a'))
+//                     + 10);
+//             }
+//             throw new ArgumentException("digit");
+//         }
+//         //
+//         // GetHashCode
+//         //
+//         //  Overrides default function (in Object class)
+//         //
+//         //
+//         [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
+//         public override int GetHashCode() {
+//             if (IsNotAbsoluteUri)
+//             {
+//                 return CalculateCaseInsensitiveHashCode(OriginalString);
+//             }
+//
+//             // Consider moving hash code storage from m_Info.MoreInfo to m_Info
+//             UriInfo info = EnsureUriInfo();
+//             if ((object)info.MoreInfo == null) {
+//                 info.MoreInfo = new MoreInfo();
+//             }
+//             int tempHash = info.MoreInfo.Hash;
+//             if (tempHash == 0) {
+//                 string chkString = info.MoreInfo.RemoteUrl;
+//                 if ((object) chkString == null)
+//                     chkString = GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped);
+//                 tempHash = CalculateCaseInsensitiveHashCode(chkString);
+//                 if (tempHash == 0) {
+//                     tempHash = 0x1000000;   //making it not zero still large enough to be maped to zero by a hashtable
+//                 }
+//                 info.MoreInfo.Hash = tempHash;
+//             }
+//             return tempHash;
+//         }
+//
+//         //
+//         // ToString
+//         //
+//         // The better implementation would be just
+//         //
+//         private const UriFormat V1ToStringUnescape = (UriFormat)0x7FFF;
+//
+//         [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
+//         public override string ToString()
+//         {
+//             if (m_Syntax == null) {
+//                 return (m_iriParsing && InFact(Flags.HasUnicode)) ? m_String : OriginalString;
+//             }
+//
+//             EnsureUriInfo();
+//             if ((object)m_Info.String == null)
+//             {
+//
+//                 // V1.1 compat unless #353711 is appoved, otheriwse it should be just a call into GetParts() as shown below
+//                 // m_Info.String = GetParts(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
+//
+//                 if (Syntax.IsSimple)
+//                     m_Info.String = GetComponentsHelper(UriComponents.AbsoluteUri, V1ToStringUnescape);
+//                 else
+//                     m_Info.String = GetParts(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
+//
+//             }
+//             return m_Info.String;
+//         }
+//
+//         //
+//         //
+//         //  A static shortcut to Uri.Equals
+//         //
+//         [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
+//         public static bool operator == (Uri uri1, Uri uri2) {
+//             if ((object)uri1 == (object)uri2) {
+//                 return true;
+//             }
+//             if ((object)uri1 == null || (object)uri2 == null) {
+//                 return false;
+//             }
+//             return uri2.Equals(uri1);
+//         }
+//
+//         //
+//         //
+//         //  A static shortcut to !Uri.Equals
+//         //
+//         [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
+//         public static bool operator != (Uri uri1, Uri uri2) {
+//             if ((object)uri1 == (object)uri2) {
+//                 return false;
+//             }
+//
+//             if ((object)uri1 == null || (object)uri2 == null) {
+//                 return true;
+//             }
+//
+//             return !uri2.Equals(uri1);
+//         }
+//
+//
+//
+//         //
+//         // Equals
+//         //
+//         //  Overrides default function (in Object class)
+//         //
+//         // Assumes:
+//         //  <comparand> is an object of class Uri
+//         //
+//         // Returns:
+//         //  true if objects have the same value, else false
+//         //
+//         // Throws:
+//         //  Nothing
+//         //
+//         [SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
+//         public override bool Equals(object comparand) {
+//             if ((object) comparand == null) {
+//                 return false;
+//             }
+//
+//             if ((object)this == (object)comparand) {
+//                 return true;
+//             }
+//
+//             Uri obj = comparand as Uri;
+//
+//             //
+//             // we allow comparisons of Uri and String objects only. If a string
+//             // is passed, convert to Uri. This is inefficient, but allows us to
+//             // canonicalize the comparand, making comparison possible
+//             //
+//             if ((object)obj == null) {
+//                 string s = comparand as string;
+//
+//                 if ((object)s == null)
+//                     return false;
+//
+//                 if (!TryCreate(s, UriKind.RelativeOrAbsolute, out obj))
+//                     return false;
+//             }
+//
+//             // Since v1.0 two Uris are equal if everything but fragment and UserInfo does match
+//
+//             // This check is for a case where we already fixed up the equal references
+//             if ((object)this.m_String == (object)obj.m_String) {
+//                 return true;
+//             }
+//
+//             if (IsAbsoluteUri != obj.IsAbsoluteUri)
+//                 return false;
+//
+//             if (IsNotAbsoluteUri)
+//                 return OriginalString.Equals(obj.OriginalString);
+//
+//             if (NotAny(Flags.AllUriInfoSet) || obj.NotAny(Flags.AllUriInfoSet)) {
+//                 // Try raw compare for m_Strings as the last chance to keep the working set small
+//                 if (!IsUncOrDosPath ) {
+//                     if (m_String.Length == obj.m_String.Length) {
+//                         unsafe {
+//                             // Try case sensitive compare on m_Strings
+//                             fixed (char* pMe = m_String) {
+//                                 fixed (char* pShe = obj.m_String) {
+//                                     // This will never go negative since m_String is checked to be a valid URI
+//                                     int i = (m_String.Length-1);
+//                                     for ( ;i >= 0 ; --i) {
+//                                         if (*(pMe+i) != *(pShe+i)) {
+//                                             break;
+//                                         }
+//                                     }
+//                                     if (i == -1) {
+//                                         return true;
+//                                     }
+//                                 }
+//                             }
+//                         }
+//                     }
+//                 }
+//                 else if (String.Compare(m_String, obj.m_String, StringComparison.OrdinalIgnoreCase) == 0) {
+//                     return true;
+//                 }
+//             }
+//
+//             // Note that equality test will bring the working set of both
+//             // objects up to creation of m_Info.MoreInfo member
+//             EnsureUriInfo();
+//             obj.EnsureUriInfo();
+//
+//             if (!UserDrivenParsing && !obj.UserDrivenParsing && Syntax.IsSimple && obj.Syntax.IsSimple)
+//             {
+//                 // Optimization of canonical DNS names by avoiding host string creation.
+//                 // Note there could be explicit ports specified that would invalidate path offsets
+//                 if (InFact(Flags.CanonicalDnsHost) && obj.InFact(Flags.CanonicalDnsHost)) {
+//                     ushort i1 = m_Info.Offset.Host;
+//                     ushort end1 = m_Info.Offset.Path;
+//
+//                     ushort i2 = obj.m_Info.Offset.Host;
+//                     ushort end2 = obj.m_Info.Offset.Path;
+//                     string str = obj.m_String;
+//                     //Taking the shortest part
+//                     if (end1-i1 > end2-i2) {
+//                         end1 = (ushort)(i1 + end2-i2);
+//                     }
+//                     // compare and break on ':' if found
+//                     while (i1 < end1) {
+//                         if (m_String[i1] != str[i2]) {
+//                             return false;
+//                         }
+//                         if (str[i2] == ':') {
+//                             // The other must have ':' too to have equal host
+//                             break;
+//                         }
+//                         ++i1;++i2;
+//                     }
+//
+//                     // The longest host must have ':' or be of the same size
+//                     if (i1 < m_Info.Offset.Path && m_String[i1] != ':') {
+//                         return false;
+//                     }
+//                     if (i2 < end2 && str[i2] != ':') {
+//                         return false;
+//                     }
+//                     //hosts are equal!
+//                 }
+//                 else {
+//                     EnsureHostString(false);
+//                     obj.EnsureHostString(false);
+//                     if (!m_Info.Host.Equals(obj.m_Info.Host)) {
+//                         return false;
+//                     }
+//                 }
+//
+//                 if (Port != obj.Port) {
+//                     return false;
+//                 }
+//             }
+//
+//             // see Whidbey#21590
+//             // We want to cache RemoteUrl to improve perf for Uri as a key.
+//             // We should consider reducing the overall working set by not caching some other properties mentioned in MoreInfo
+//
+//             // Mutli-threading!
+//             UriInfo meInfo  = m_Info;
+//             UriInfo sheInfo = obj.m_Info;
+//             if ((object)meInfo.MoreInfo == null) {
+//                 meInfo.MoreInfo = new MoreInfo();
+//             }
+//             if ((object)sheInfo.MoreInfo == null) {
+//                 sheInfo.MoreInfo = new MoreInfo();
+//             }
+//
+//             // NB: To avoid a race condition when creating MoreInfo field
+//             // "meInfo" and "sheInfo" shall remain as local copies.
+//             string me = meInfo.MoreInfo.RemoteUrl;
+//             if ((object)me == null) {
+//                 me = GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped);
+//                 meInfo.MoreInfo.RemoteUrl = me;
+//             }
+//             string she = sheInfo.MoreInfo.RemoteUrl;
+//             if ((object)she == null) {
+//                 she = obj.GetParts(UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped);
+//                 sheInfo.MoreInfo.RemoteUrl = she;
+//             }
+//
+//             if (!IsUncOrDosPath ) {
+//                 if (me.Length != she.Length) {
+//                     return false;
+//                 }
+//                 unsafe {
+//                     // Try case sensitive compare on m_Strings
+//                     fixed (char* pMe = me) {
+//                         fixed (char* pShe = she) {
+//                             char *endMe  = pMe  + me.Length;
+//                             char *endShe = pShe + me.Length;
+//                             while (endMe != pMe) {
+//                                 if (*--endMe != *--endShe) {
+//                                     return false;
+//                                 }
+//                             }
+//                             return true;
+//                         }
+//                     }
+//                 }
+//             }
+//
+//
+//             // if IsUncOrDosPath is true then we ignore case in the path comparison
+//             // Get Unescaped form as most safe for the comparison
+//             // Fragment AND UserInfo are ignored
+//             //
+//             return (String.Compare(meInfo.MoreInfo.RemoteUrl,
+//                                    sheInfo.MoreInfo.RemoteUrl,
+//                                    IsUncOrDosPath ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal ) == 0);
+//         }
+//         //
+//         public Uri MakeRelativeUri(Uri uri)
+//         {
+//             if ((object)uri == null)
+//                 throw new ArgumentNullException("uri");
+//
+//             if (IsNotAbsoluteUri || uri.IsNotAbsoluteUri)
+//                 throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//
+//             // Note that the UserInfo part is ignored when computing a relative Uri.
+//             if ((Scheme == uri.Scheme) && (Host == uri.Host) && (Port == uri.Port))
+//             {
+//                 String otherPath = uri.AbsolutePath;
+//
+//                 // Relative Path
+//                 String relativeUriString = PathDifference(AbsolutePath, otherPath, !IsUncOrDosPath);
+//
+//                 // Relative Uri's cannot have a colon ':' in the first path segment (RFC 3986, Section 4.2)
+//                 if (CheckForColonInFirstPathSegment(relativeUriString)
+//                     // Except for full implicit dos file paths
+//                     && !(uri.IsDosPath && otherPath.Equals(relativeUriString, StringComparison.Ordinal)))
+//                     relativeUriString = "./" + relativeUriString;
+//                 
+//                 // Query & Fragment
+//                 relativeUriString += uri.GetParts(UriComponents.Query | UriComponents.Fragment, UriFormat.UriEscaped);
+//
+//                 return new Uri(relativeUriString, UriKind.Relative);
+//             }
+//             return uri;
+//         }
+//
+//         //
+//         // http://www.ietf.org/rfc/rfc3986.txt
+//         // 
+//         // 3.3.  Path
+//         // In addition, a URI reference (Section 4.1) may be a relative-path reference, in which case the  first 
+//         // path segment cannot contain a colon (":") character.
+//         // 
+//         // 4.2.  Relative Reference
+//         // A path segment that contains a colon character (e.g., "this:that") cannot be used as the first segment 
+//         // of a relative-path reference, as it would be mistaken for a scheme name.  Such a segment must be   
+//         // preceded by a dot-segment (e.g., "./this:that") to make a relative-path reference.
+//         // 
+//         // 5.4.2. Abnormal Examples 
+//         // http:(relativeUri) may be considered a valid relative Uri.
+//         // 
+//         // Returns true if a colon is found in the first path segment, false otherwise
+//         // 
+//         private static bool CheckForColonInFirstPathSegment(String uriString)
+//         {
+//             // Check for anything that may terminate the first regular path segment
+//             // or an illegal colon
+//             char[] pathDelims = new char[] { ':', '\\', '/', '?', '#' };
+//             int index = uriString.IndexOfAny(pathDelims);
+//
+//             return (index >= 0 && uriString[index] == ':');
+//         }
+//         // This is used by UriBuilder, 
+//
+//         internal unsafe static string InternalEscapeString(string rawString) {
+//             if ((object)rawString == null)
+//                 return String.Empty;
+//
+//             int position = 0;
+//             char[] dest = UriHelper.EscapeString(rawString, 0, rawString.Length, null, ref position, true, '?', '#', '%');
+//             if ((object)dest == null)
+//                 return rawString;
+//
+//             return new string(dest, 0, position);
+//         }
+//
+//         //
+//         //  This method is called first to figure out the scheme or a simple file path
+//         //  Is called only at the .ctor time
+//         //
+//         private static unsafe ParsingError ParseScheme(string uriString, ref Flags flags, ref UriParser syntax)
+//         {
+//             int length = uriString.Length;
+//             if (length == 0)
+//                 return ParsingError.EmptyUriString;
+//
+//             // we don;t work with >= 64k Uris
+//             if (length >= c_MaxUriBufferSize)
+//                 return ParsingError.SizeLimit;
+//
+//             //STEP1: parse scheme, lookup this Uri Syntax or create one using UnknownV1SyntaxFlags uri syntax template
+//             fixed (char* pUriString = uriString)
+//             {
+//                 ParsingError err = ParsingError.None;
+//                 ushort idx = ParseSchemeCheckImplicitFile(pUriString, (ushort)length, ref err, ref flags, ref syntax);
+//
+//                 if (err != ParsingError.None)
+//                     return err;
+//
+//                 flags |= (Flags)idx;
+//              }
+//              return ParsingError.None;
+//         }
+//
+//         //
+//         // A wrapper for ParseMinimal() called from a user parser
+//         // It signals back that the call has been done
+//         // plus it communicates back a flag for an error if any
+//         //
+//         internal UriFormatException ParseMinimal()
+//         {
+//             ParsingError result = PrivateParseMinimal();
+//             if (result == ParsingError.None)
+//                 return null;
+//
+//             // Means the we think the Uri is invalid, bu that can be later overriden by a user parser
+//             m_Flags |= Flags.ErrorOrParsingRecursion;
+//
+//             return GetException(result);
+//         }
+//         //
+//         //
+//         //  This method tries to parse the minimal information needed to certify the valifity
+//         //  of a uri string
+//         //
+//         //      scheme://userinfo@host:Port/Path?Query#Fragment
+//         //
+//         //  The method must be called only at the .ctor time
+//         //
+//         //  Returns ParsingError.None if the Uri syntax is valid, an error otheriwse
+//         //
+//         private unsafe ParsingError PrivateParseMinimal()
+//         {
+//             ushort idx = (ushort) (m_Flags & Flags.IndexMask);
+//             ushort length = (ushort) m_String.Length;
+//             string newHost = null;      // stores newly parsed host when original strings are being switched
+//
+//             // Means a custom UriParser did call "base" InitializeAndValidate()
+//             m_Flags &= ~(Flags.IndexMask | Flags.UserDrivenParsing);
+//
+//             //STEP2: Parse up to the port
+//
+//             fixed (char* pUriString =   ((m_iriParsing &&
+//                                         ((m_Flags & Flags.HasUnicode)!=0) &&
+//                                         ((m_Flags & Flags.HostUnicodeNormalized) == 0)) ? m_originalUnicodeString : m_String))
+//             {
+//                 // Cut trailing spaces in m_String
+//                 if (length > idx && IsLWS(pUriString[length-1]))
+//                 {
+//                     --length;
+//                     while (length != idx && IsLWS(pUriString[--length]))
+//                         ;
+//                     ++length;
+//                 }
+//
+//                 // Microsoft codereview:
+//                 // Old Uri parser tries to figure out on a DosPath in all cases.
+//                 // Hence http://c:/ is treated as as DosPath without the host while it should be a host "c", port 80
+//                 //
+//                 // This block is compatible with Old Uri parser in terms it will look for the DosPath if the scheme
+//                 // syntax allows both empty hostnames and DosPath
+//                 //
+// #if !PLATFORM_UNIX
+//                 if (m_Syntax.IsAllSet(UriSyntaxFlags.AllowEmptyHost | UriSyntaxFlags.AllowDOSPath) 
+//                     && NotAny(Flags.ImplicitFile) && (idx + 1 < length)) {
+//
+//                     char c;
+//                     ushort i = (ushort) idx;
+//
+//                     // V1 Compat: Allow _compression_ of > 3 slashes only for File scheme, see VsWhidbey 87448.
+//                     // This will skip all slashes and if their number is 2+ it sets the AuthorityFound flag
+//                     for (; i < length; ++i) {
+//                         if (!((c=pUriString[i])== '\\' || c == '/'))
+//                             break;
+//                     }
+//
+//                     if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri) || i-idx <= 3) {
+//                         // if more than one slash after the scheme, the authority is present
+//                         if (i-idx >= 2) {
+//                             m_Flags |= Flags.AuthorityFound;
+//                         }
+//                         // DOS-like path?
+//                         if (i+1 < (ushort) length  && ((c=pUriString[i+1]) == ':' || c == '|') && 
+//                             IsAsciiLetter(pUriString[i])) {
+//
+//                             if (i+2 >= (ushort) length || ((c=pUriString[i+2]) != '\\' && c != '/'))
+//                             {
+//                                 // report an error but only for a file: scheme
+//                                 if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri))
+//                                     return ParsingError.MustRootedPath;
+//                             }
+//                             else
+//                             {
+//                                 // This will set IsDosPath
+//                                 m_Flags |= Flags.DosPath;
+//
+//                                 if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority)) {
+//                                     // when DosPath found and Authority is required, set this flag even if Authority is empty
+//                                     m_Flags |= Flags.AuthorityFound;
+//                                 }
+//                                 if (i != idx && i-idx != 2) {
+//                                     //This will remember that DosPath is rooted
+//                                     idx = (ushort)(i-1);
+//                                 }
+//                                 else {
+//                                     idx = i;
+//                                 }
+//                             }
+//                         }
+//                         else if (m_Syntax.InFact(UriSyntaxFlags.FileLikeUri) && (i - idx >= 2 && i - idx != 3 && 
+//                             i < length && pUriString[i] != '?' && pUriString[i] != '#'))
+//                         {
+//                             // see VsWhidbey#226745 V1.0 did not support file:///, fixing it with minimal behavior change impact
+//                             // Only FILE scheme may have UNC Path flag set
+//                             m_Flags |= Flags.UncPath;
+//                             idx = i;
+//                         }
+//                     }
+//                 }
+// #endif // !PLATFORM_UNIX
+//                 //
+//                 //STEP 1.5 decide on the Authority component
+//                 //
+// #if !PLATFORM_UNIX
+//                 if ((m_Flags & (Flags.UncPath|Flags.DosPath)) != 0) {
+//                 }
+// #else
+//                 if ((m_Flags & Flags.ImplicitFile) != 0) {
+//                     // Already parsed up to the path
+//                 }
+// #endif // !PLATFORM_UNIX
+//                 else if ((idx+2) <= length) {
+//                     char first  = pUriString[idx];
+//                     char second = pUriString[idx+1];
+//
+//                     if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority)) {
+//                         // (V1.0 compatiblity) This will allow http:\\ http:\/ http:/\
+// #if !PLATFORM_UNIX
+//                         if ((first == '/' || first == '\\') && (second == '/' || second == '\\'))
+// #else
+//                         if (first == '/' && second == '/')
+// #endif // !PLATFORM_UNIX
+//                         {
+//                             m_Flags |= Flags.AuthorityFound;
+//                             idx+=2;
+//                         }
+//                         else {
+//                             return ParsingError.BadAuthority;
+//                         }
+//                     }
+//                     else if (m_Syntax.InFact(UriSyntaxFlags.OptionalAuthority) && (InFact(Flags.AuthorityFound) || 
+//                         (first == '/' && second == '/'))) {
+//                         m_Flags |= Flags.AuthorityFound;
+//                         idx+=2;
+//                     }
+//                     // 
+//                     else if (m_Syntax.NotAny(UriSyntaxFlags.MailToLikeUri)) {
+//                         // By now we know the URI has no Authority, so if the URI must be normalized, initialize it without one.
+//                         if (m_iriParsing && (m_Flags & Flags.HasUnicode) != 0 && (m_Flags & Flags.HostUnicodeNormalized) == 0)
+//                         {
+//                             m_String = m_String.Substring(0, idx);
+//                         }
+//                         // Since there is no Authority, the path index is just the end of the scheme.
+//                         m_Flags |= ((Flags)idx | Flags.UnknownHostType);
+//                         return ParsingError.None;
+//                     }
+//                 }
+//                 else if (m_Syntax.InFact(UriSyntaxFlags.MustHaveAuthority)) {
+//                     return ParsingError.BadAuthority;
+//                 }
+//                 // 
+//                 else if (m_Syntax.NotAny(UriSyntaxFlags.MailToLikeUri)) {
+//                     // By now we know the URI has no Authority, so if the URI must be normalized, initialize it without one.
+//                     if (m_iriParsing && (m_Flags & Flags.HasUnicode) != 0 && (m_Flags & Flags.HostUnicodeNormalized) == 0)
+//                     {
+//                         m_String = m_String.Substring(0, idx);
+//                     }
+//                     // Since there is no Authority, the path index is just the end of the scheme.
+//                     m_Flags |= ((Flags)idx | Flags.UnknownHostType);
+//                     return ParsingError.None;
+//                 }
+//
+// #if !PLATFORM_UNIX
+//                 // The following sample taken from the original parser comments makes the whole story sad
+//                 // vsmacros://c:\path\file
+//                 // Note that two slashes say there must be an Authority but instead the path goes
+//                 // Fro V1 compat the next block allow this case but not for schemes like http
+//                 if (InFact(Flags.DosPath)) {
+//
+//                     m_Flags |= (((m_Flags & Flags.AuthorityFound)!= 0)? Flags.BasicHostType :Flags.UnknownHostType);
+//                     m_Flags |= (Flags)idx;
+//                     return ParsingError.None;
+//                 }
+// #endif // !PLATFORM_UNIX
+//
+//                 //STEP 2: Check the syntax of authority expecting at least one character in it
+//                 //
+//                 // Note here we do know that there is an authority in the string OR it's a DOS path
+//
+//                 // We may find a userInfo and the port when parsing an authority
+//                 // Also we may find a registry based authority.
+//                 // We must ensure that known schemes do use a server-based authority
+//             {
+//                 ParsingError err = ParsingError.None;
+//                 idx = CheckAuthorityHelper(pUriString, idx, (ushort)length, ref err, ref m_Flags, m_Syntax, ref newHost);
+//                 if (err != ParsingError.None)
+//                     return err;
+//
+//                 // This will disallow '\' as the host terminator for any scheme that is not implicitFile or cannot have a Dos Path
+//                 if ((idx < (ushort)length && pUriString[idx] == '\\') && NotAny(Flags.ImplicitFile) && 
+//                     m_Syntax.NotAny(UriSyntaxFlags.AllowDOSPath)) {
+//                     return ParsingError.BadAuthorityTerminator;
+//                 }
+//
+//             }
+//
+//                 // The Path (or Port) parsing index is reloaded on demand in CreateUriInfo when accessing a Uri property
+//                 m_Flags |= (Flags)idx;
+//
+//                 // The rest of the string will be parsed on demand
+//                 // The Host/Authorty is all checked, the type is known but the host value string
+//                 // is not created/canonicalized at this point.
+//             }
+//
+//             if((s_IdnScope != UriIdnScope.None) || m_iriParsing)
+//                 PrivateParseMinimalIri(newHost, idx);
+//
+//             return ParsingError.None;
+//         }
+//
+//         private void PrivateParseMinimalIri(string newHost, ushort idx)
+//         {
+//             // we have a new host!
+//             if (newHost != null)
+//                 m_String = newHost;
+//
+//             // conditions where we dont need to go to parseremaining, so we copy the rest of the
+//             // original string.. and switch offsets
+//             if ((!m_iriParsing && AllowIdn && (((m_Flags & Flags.IdnHost) != 0) || ((m_Flags & Flags.UnicodeHost) != 0))) ||
+//                 (m_iriParsing && ((m_Flags & Flags.HasUnicode) == 0) && AllowIdn && ((m_Flags & Flags.IdnHost) != 0))){
+//                 // update the start of path from the end of new string
+//                 m_Flags &= ~(Flags.IndexMask);
+//                 m_Flags |= (Flags)m_String.Length;
+//
+//                 m_String += m_originalUnicodeString.Substring(idx, m_originalUnicodeString.Length - idx);
+//             }
+//
+//             // Indicate to createuriinfo that offset is in m_originalUnicodeString
+//             if (m_iriParsing && ((m_Flags & Flags.HasUnicode) != 0)){
+//                 // offset in Flags.IndexMask refers to m_originalUnicodeString
+//                 m_Flags |= Flags.UseOrigUncdStrOffset;
+//             }
+//         }
+//
+//         //
+//         //
+//         // The method is called when we have to access m_Info members
+//         // This will create the m_Info based on the copied parser context
+//         // Under milti-threading ---- this method may do duplicated yet harmless work
+//         //
+//         private unsafe void CreateUriInfo(Flags cF) {
+//
+//             UriInfo info = new UriInfo();
+//
+//             // This will be revisited in ParseRemaining but for now just have it at least m_String.Length
+//             info.Offset.End = (ushort)m_String.Length;
+//
+//             if (UserDrivenParsing)
+//                 goto Done;
+//
+//             ushort idx;
+//             bool notCanonicalScheme = false;
+//
+//             // The m_String may have leading spaces, figure that out
+//             // plus it will set idx value for next steps
+//             if ((cF & Flags.ImplicitFile) != 0) {
+//                 idx = (ushort)0;
+//                 while (IsLWS(m_String[idx])) {
+//                     ++idx;
+//                     ++info.Offset.Scheme;
+//                 }
+//
+// #if !PLATFORM_UNIX
+//                 if (StaticInFact(cF, Flags.UncPath)) {
+//                     // For implicit file AND Unc only
+//                     idx += 2;
+//                     //skip any other slashes (compatibility with V1.0 parser)
+//                     while(idx < (ushort)(cF & Flags.IndexMask) && (m_String[idx] == '/' || m_String[idx] == '\\')) {
+//                         ++idx;
+//                     }
+//                 }
+// #endif // !PLATFORM_UNIX
+//             }
+//             else {
+//                 // This is NOT an ImplicitFile uri
+//                 idx = (ushort)m_Syntax.SchemeName.Length;
+//
+//                 while (m_String[idx++] != ':') {
+//                     ++info.Offset.Scheme;
+//                 }
+//
+//                 if ((cF & Flags.AuthorityFound) != 0)
+//                 {
+//                     if (m_String[idx] == '\\' || m_String[idx+1] == '\\')
+//                         notCanonicalScheme = true;
+//
+//                     idx+=2;
+// #if !PLATFORM_UNIX
+//                     if ((cF & (Flags.UncPath|Flags.DosPath)) != 0) {
+//                         // Skip slashes if it was allowed during ctor time
+//                         // NB: Today this is only allowed if a Unc or DosPath was found after the scheme
+//                         while( idx < (ushort)(cF & Flags.IndexMask) && (m_String[idx] == '/' || m_String[idx] == '\\')) {
+//                             notCanonicalScheme = true;
+//                             ++idx;
+//                         }
+//                     }
+// #endif // !PLATFORM_UNIX
+//                 }
+//             }
+//
+//             // This is weird but some schemes (mailto) do not have Authority-based syntax, still they do have a port
+//             if (m_Syntax.DefaultPort != UriParser.NoDefaultPort)
+//                 info.Offset.PortValue = (ushort)m_Syntax.DefaultPort;
+//
+//             //Here we set the indexes for already parsed components
+//             if ((cF & Flags.HostTypeMask) == Flags.UnknownHostType
+// #if !PLATFORM_UNIX
+//                 || StaticInFact(cF, Flags.DosPath)
+// #endif // !PLATFORM_UNIX
+//                 ) {
+//                 //there is no Authotity component defined
+//                 info.Offset.User  = (ushort) (cF & Flags.IndexMask);
+//                 info.Offset.Host = info.Offset.User;
+//                 info.Offset.Path = info.Offset.User;
+//                 cF &= ~Flags.IndexMask;
+//                 if (notCanonicalScheme) {
+//                     cF |= Flags.SchemeNotCanonical;
+//                 }
+//                 goto Done;
+//             }
+//
+//             info.Offset.User = idx;
+//
+//             //Basic Host Type does not have userinfo and port
+//             if (HostType == Flags.BasicHostType) {
+//                 info.Offset.Host = idx;
+//                 info.Offset.Path = (ushort) (cF & Flags.IndexMask);
+//                 cF &= ~Flags.IndexMask;
+//                 goto Done;
+//             }
+//
+//             if ((cF & Flags.HasUserInfo) != 0) {
+//                 // we previously found a userinfo, get it again
+//                 while (m_String[idx] != '@') {
+//                     ++idx;
+//                 }
+//                 ++idx;
+//                 info.Offset.Host = idx;
+//             }
+//             else {
+//                 info.Offset.Host = idx;
+//             }
+//
+//             //Now reload the end of the parsed host
+//
+//             idx = (ushort) (cF & Flags.IndexMask);
+//
+//             //From now on we do not need IndexMask bits, and reuse the space for X_NotCanonical flags
+//             //clear them now
+//             cF &= ~Flags.IndexMask;
+//
+//             // If this is not canonical, don't count on user input to be good
+//             if (notCanonicalScheme) {
+//                 cF |= Flags.SchemeNotCanonical;
+//             }
+//
+//             //Guessing this is a path start
+//             info.Offset.Path = idx;
+//
+//             // parse Port if any. The new spec allows a port after ':' to be empty (assuming default?)
+//             bool notEmpty = false;
+//             // Note we already checked on general port syntax in ParseMinimal()
+//
+//             // If iri parsing is on with unicode chars then the end of parsed host
+//             // points to m_orig string and not m_String
+//
+//             bool UseOrigUnicodeStrOffset = ((cF& Flags.UseOrigUncdStrOffset) != 0);
+//             // This should happen only once. Reset it
+//             cF &= ~Flags.UseOrigUncdStrOffset;
+//
+//             if (UseOrigUnicodeStrOffset)
+//                 info.Offset.End = (ushort)m_originalUnicodeString.Length;
+//
+//             if (idx < info.Offset.End ){
+//                 fixed (char* userString = UseOrigUnicodeStrOffset ? m_originalUnicodeString : m_String){
+//                     if (userString[idx] == ':'){
+//                         int port = 0;
+//
+//                         //Check on some noncanonical cases http://host:0324/, http://host:03, http://host:0, etc
+//                         if (++idx < info.Offset.End){
+//                             port = (ushort)(userString[idx] - '0');
+//                             if (!(port == unchecked((ushort)('/' - '0')) || port == (ushort)('?' - '0') || 
+//                                 port == unchecked((ushort)('#' - '0')))) {
+//                                 notEmpty = true;
+//                                 if (port == 0){
+//                                     cF |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
+//                                 }
+//                                 for (++idx; idx < info.Offset.End; ++idx){
+//                                     ushort val = (ushort)((ushort)userString[idx] - (ushort)'0');
+//                                     if (val == unchecked((ushort)('/' - '0')) || val == (ushort)('?' - '0') || 
+//                                         val == unchecked((ushort)('#' - '0'))){
+//                                         break;
+//                                     }
+//                                     port = (port * 10 + val);
+//                                 }
+//                             }
+//                         }
+//                         if (notEmpty && info.Offset.PortValue != (ushort)port){
+//                             info.Offset.PortValue = (ushort)port;
+//                             cF |= Flags.NotDefaultPort;
+//                         }
+//                         else{
+//                             //This will tell that we do have a ':' but the port value does
+//                             //not follow to canonical rules
+//                             cF |= (Flags.PortNotCanonical | Flags.E_PortNotCanonical);
+//                         }
+//                         info.Offset.Path = (ushort)idx;
+//                     }
+//                 }
+//             }
+//
+//         Done:
+//             cF |= Flags.MinimalUriInfoSet;
+// /*********
+//             // The spinlock would be better than below lock but it's too late for Beta2, consider for RTM
+//             // Also DON'T forget to check EnsureUriInfo method
+//             int copyF = m_Flags;
+//             while ((copyF & Flags.MinimalUriInfoSet) == 0)
+//             {
+//                if (copyF != (copyF = Interlocked.CompareExchange(ref m_Flags, cF | (copyF & ~Flags.IndexMask), copyF))
+//                    continue;
+//                m_Info  = info;
+//             }
+// *********/
+//             info.DnsSafeHost = m_DnsSafeHost;
+//             lock (m_String)
+//             {
+//                 if (( m_Flags & Flags.MinimalUriInfoSet) == 0)
+//                 {
+//                     m_Info  = info;
+//                     m_Flags = (m_Flags & ~Flags.IndexMask) | cF;
+//                 }
+//             }
+//
+//         }
+//
+//         //
+//         // This will create a Host string. The validity has been already checked
+//         //
+//         // Assuming: UriInfo memeber is already set at this point
+//         private unsafe void CreateHostString() {
+//             //
+//             // Mutlithrreading!
+//             //
+//             if (!m_Syntax.IsSimple)
+//             {
+//                 lock (m_Info)
+//                 {
+//                     // ATTN: Avoid possible recursion through 
+//                     // CreateHostString->Syntax.GetComponents->Uri.GetComponentsHelper->CreateHostString
+//                     if (NotAny(Flags.ErrorOrParsingRecursion))
+//                     {
+//                         m_Flags |= Flags.ErrorOrParsingRecursion;
+//                         // Need to get host string through the derived type
+//                         GetHostViaCustomSyntax();
+//                         m_Flags &= ~Flags.ErrorOrParsingRecursion;
+//                         return;
+//                     }
+//                 }
+//             }
+//             Flags flags = m_Flags;
+//             string host = CreateHostStringHelper(m_String, m_Info.Offset.Host, m_Info.Offset.Path, ref flags, ref m_Info.ScopeId);
+//
+//             // now check on canonical host representation
+//             if (host.Length != 0)
+//             {
+//                 // An Authority may need escaping except when it's an inet server address
+//                 //
+//                 // We do not escape UNC names and will get rid of this type when switching to IDN spec
+//                 //
+//                 if (HostType == Flags.BasicHostType) {
+//                     ushort idx = 0;
+//                     Check result;
+//                     fixed (char* pHost = host) {
+//                         result = CheckCanonical(pHost, ref idx, (ushort)host.Length, c_DummyChar);
+//                     }
+//
+//                     if ((result & Check.DisplayCanonical) == 0) {
+//                         // For implicit file the user string must be in perfect display format,
+//                         // Hence, ignoring complains from CheckCanonical()
+//                         if (NotAny(Flags.ImplicitFile) || (result & Check.ReservedFound) != 0) {
+//                             flags |= Flags.HostNotCanonical;
+//                         }
+//                     }
+//
+//                     if (InFact(Flags.ImplicitFile) && (result & (Check.ReservedFound | Check.EscapedCanonical)) != 0) {
+//                         // need to re-escape this host if any escaped sequence was found
+//                         result &= ~Check.EscapedCanonical;
+//                     }
+//
+//                     if ((result & (Check.EscapedCanonical|Check.BackslashInPath)) != Check.EscapedCanonical) {
+//                         // we will make a canonical host in m_Info.Host, but mark that m_String holds wrong data
+//                         flags |= Flags.E_HostNotCanonical;
+//                         if (NotAny(Flags.UserEscaped))
+//                         {
+//                             int position = 0;
+//                             char[] dest = UriHelper.EscapeString(host, 0, host.Length, null, ref position, true, '?',
+//                                 '#', IsImplicitFile ? c_DummyChar : '%');
+//                             if ((object)dest != null)
+//                                 host = new string(dest, 0, position);
+//                         }
+//                         else {
+//                             // 
+//
+//                         }
+//                     }
+//                 }
+//                 else if (NotAny(Flags.CanonicalDnsHost)){
+//                     // Check to see if we can take the canonical host string out of m_String
+//                     if ((object)m_Info.ScopeId != null) {
+//                         // IPv6 ScopeId is included when serializing a Uri
+//                         flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
+//                     }
+//                     else {
+//                         for (int i=0 ; i < host.Length; ++i) {
+//                              if ((m_Info.Offset.Host + i) >= m_Info.Offset.End || 
+//                                  host[i] != m_String[m_Info.Offset.Host + i]) {
+//                                  flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
+//                                  break;
+//                              }
+//                          }
+//                     }
+//                 }
+//             }
+//
+//             m_Info.Host = host;
+//             lock (m_Info)
+//             {
+//                 m_Flags |= flags;
+//             }
+//         }
+//         //
+//         private static string CreateHostStringHelper(string str, ushort idx, ushort end, ref Flags flags, ref string scopeId)
+//         {
+//             bool loopback = false;
+//             string host;
+//             switch (flags & Flags.HostTypeMask) {
+//
+//                 case Flags.DnsHostType:
+//                     host = DomainNameHelper.ParseCanonicalName(str, idx, end, ref loopback);
+//                     break;
+//
+//                 case Flags.IPv6HostType:
+//                     //Microsoft codereview
+//                     // The helper will return [...] string that is not suited for Dns.Resolve()
+//                     host = IPv6AddressHelper.ParseCanonicalName(str, idx, ref loopback, ref scopeId);
+//                     break;
+//
+//                 case Flags.IPv4HostType:
+//                     host = IPv4AddressHelper.ParseCanonicalName(str, idx, end, ref loopback);
+//                     break;
+//
+// #if !PLATFORM_UNIX
+//                 case Flags.UncHostType:
+//                     host = UncNameHelper.ParseCanonicalName(str, idx, end, ref loopback);
+//                     break;
+// #endif // !PLATFORM_UNIX
+//
+//                 case Flags.BasicHostType:
+// #if !PLATFORM_UNIX
+//                     if (StaticInFact(flags, Flags.DosPath)) {
+//                         host = string.Empty;
+//                     }
+//                     else
+// #endif // !PLATFORM_UNIX
+//                     {
+//                         // This is for a registry-based authority, not relevant for known schemes
+//                         host = str.Substring(idx, end-idx);
+//                     }
+//                     // A empty host would count for a loopback
+//                     if (host.Length == 0) {
+//                         loopback = true;
+//                     }
+//                     //there will be no port
+//                     break;
+//
+//                 case Flags.UnknownHostType:
+//                     //means the host is *not expected* for this uri type
+//                     host = string.Empty;
+//                     break;
+//
+//                 default: //it's a bug
+//                     throw GetException(ParsingError.BadHostName);
+//             }
+//
+//             if (loopback) {
+//                 flags |= Flags.LoopbackHost;
+//             }
+//             return host;
+//         }
+//         //
+//         // Called under lock()
+//         //
+//         private unsafe void GetHostViaCustomSyntax()
+//         {
+//             // A multithreading check
+//             if (m_Info.Host != null)
+//                 return;
+//
+//             string host = m_Syntax.InternalGetComponents(this, UriComponents.Host, UriFormat.UriEscaped);
+//
+//             // ATTN: Check on whether recursion has not happened
+//             if ((object)m_Info.Host == null)
+//             {
+//                 if (host.Length >= c_MaxUriBufferSize)
+//                     throw GetException(ParsingError.SizeLimit);
+//
+//                 ParsingError err = ParsingError.None;
+//                 Flags flags = m_Flags & ~Flags.HostTypeMask;
+//
+//                 fixed (char *pHost = host)
+//                 {
+//                     string newHost = null;
+//                     if (CheckAuthorityHelper(pHost, 0, (ushort)host.Length, ref err, ref flags, m_Syntax, ref newHost) != 
+//                         (ushort)host.Length)
+//                     {
+//                         // We cannot parse the entire host string
+//                         flags &= ~Flags.HostTypeMask;
+//                         flags |= Flags.UnknownHostType;
+//                     }
+//                 }
+//
+//                 if (err != ParsingError.None || (flags & Flags.HostTypeMask) == Flags.UnknownHostType)
+//                 {
+//                     // Well, custom parser has returned a not known host type, take it as Basic then.
+//                     m_Flags = (m_Flags & ~Flags.HostTypeMask) | Flags.BasicHostType;
+//                 }
+//                 else
+//                 {
+//                     host = CreateHostStringHelper(host, 0, (ushort)host.Length, ref flags, ref m_Info.ScopeId);
+//                     for (int i=0 ; i < host.Length; ++i) {
+//                              if ((m_Info.Offset.Host + i) >= m_Info.Offset.End || host[i] != m_String[m_Info.Offset.Host + i]) {
+//                                  m_Flags |= (Flags.HostNotCanonical | Flags.E_HostNotCanonical);
+//                                  break;
+//                              }
+//                          }
+//                     m_Flags = (m_Flags & ~Flags.HostTypeMask) | (flags & Flags.HostTypeMask);
+//                 }
+//             }
+//             //
+//             // This is a chance for a custom parser to report a different port value
+//             //
+//             string portStr = m_Syntax.InternalGetComponents(this, UriComponents.StrongPort, UriFormat.UriEscaped);
+//             int port = 0;
+//             if ((object)portStr == null || portStr.Length == 0)
+//             {
+//                 // It's like no port
+//                 m_Flags &= ~Flags.NotDefaultPort;
+//                 m_Flags |= (Flags.PortNotCanonical|Flags.E_PortNotCanonical);
+//                 m_Info.Offset.PortValue = 0;
+//             }
+//             else
+//             {
+//                 for (int idx=0; idx < portStr.Length; ++idx)
+//                 {
+//                     int val = portStr[idx] - '0';
+//                     if (val < 0 || val > 9 || (port = (port * 10 + val)) > 0xFFFF)
+//                         throw new UriFormatException(SR.GetString(SR.net_uri_PortOutOfRange, m_Syntax.GetType().FullName, portStr));
+//                 }
+//                 if (port != m_Info.Offset.PortValue)
+//                 {
+//                     if (port == m_Syntax.DefaultPort)
+//                         m_Flags &= ~Flags.NotDefaultPort;
+//                     else
+//                         m_Flags |= Flags.NotDefaultPort;
+//
+//                     m_Flags |= (Flags.PortNotCanonical|Flags.E_PortNotCanonical);
+//                     m_Info.Offset.PortValue = (ushort) port;
+//                 }
+//             }
+//             // This must be done as the last thing in this method
+//             m_Info.Host = host;
+//         }
+//         //
+//         // An internal shortcut into Uri extenisiblity API
+//         //
+//         internal string GetParts(UriComponents uriParts, UriFormat formatAs)
+//         {
+//             return GetComponents(uriParts, formatAs);
+//         }
+//
+//         //
+//         //
+//         //
+//         private string GetEscapedParts(UriComponents uriParts) {
+//             // Which Uri parts are not escaped canonically ?
+//             // Notice that public UriPart and private Flags must me in Sync so below code can work
+//             //
+//             ushort  nonCanonical = (ushort)(((ushort)m_Flags & ((ushort)Flags.CannotDisplayCanonical<<7)) >> 6);
+//             if (InFact(Flags.SchemeNotCanonical)) {
+//                 nonCanonical |= (ushort)Flags.SchemeNotCanonical;
+//             }
+//
+//             // We keep separate flags for some of path canonicalization facts
+//             if ((uriParts & UriComponents.Path) != 0) {
+//                 if (InFact(Flags.ShouldBeCompressed|Flags.FirstSlashAbsent|Flags.BackslashInPath)) {
+//                     nonCanonical |= (ushort)Flags.PathNotCanonical;
+//                 }
+//                 else if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] == '|') {
+//                     // A rare case of c|\
+//                     nonCanonical |= (ushort)Flags.PathNotCanonical;
+//                 }
+//             }
+//
+//             if (((ushort)uriParts & nonCanonical) == 0) {
+//                 string ret = GetUriPartsFromUserString(uriParts);
+//                 if ((object)ret != null) {
+//                     return ret;
+//                 }
+//             }
+//
+//             return ReCreateParts(uriParts, nonCanonical, UriFormat.UriEscaped);
+//         }
+//
+//         private string GetUnescapedParts(UriComponents uriParts, UriFormat formatAs) {
+//             // Which Uri parts are not escaped canonically ?
+//             // Notice that public UriComponents and private Uri.Flags must me in Sync so below code can work
+//             //
+//             ushort  nonCanonical = (ushort)((ushort)m_Flags & (ushort)Flags.CannotDisplayCanonical);
+//
+//             // We keep separate flags for some of path canonicalization facts
+//             if ((uriParts & UriComponents.Path) != 0) {
+//                 if ((m_Flags & (Flags.ShouldBeCompressed|Flags.FirstSlashAbsent|Flags.BackslashInPath)) !=0) {
+//                     nonCanonical |= (ushort)Flags.PathNotCanonical;
+//                 }
+//                 else if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] == '|') {
+//                     // A rare case of c|\
+//                     nonCanonical |= (ushort)Flags.PathNotCanonical;
+//                 }
+//
+//             }
+//
+//             if (((ushort)uriParts & nonCanonical) == 0) {
+//                 string ret = GetUriPartsFromUserString(uriParts);
+//                 if ((object)ret != null) {
+//                     return ret;
+//                 }
+//             }
+//
+//             return ReCreateParts(uriParts, nonCanonical, formatAs);
+//         }
+//
+//         //
+//         //
+//         //
+//         private string ReCreateParts(UriComponents parts, ushort nonCanonical, UriFormat formatAs)
+//         {
+//             // going hard core
+//             EnsureHostString(false);
+//             string stemp = (parts & UriComponents.Host) == 0? string.Empty: m_Info.Host;
+//             // we reserve more space than required because a canonical Ipv6 Host
+//             // may take more characteres than in original m_String
+//             // Also +3 is for :// and +1 is for absent first slash
+//             // Also we may escape every character, hence multiplying by 12
+//             // UTF-8 can use up to 4 bytes per char * 3 chars per byte (%A4) = 12 encoded chars
+//             int count = (m_Info.Offset.End-m_Info.Offset.User) * (formatAs == UriFormat.UriEscaped?12:1);
+//             char[] chars = new char[stemp.Length + count + m_Syntax.SchemeName.Length + 3 + 1];
+//             count = 0;
+//
+//             //Scheme and slashes
+//             if ((parts & UriComponents.Scheme) != 0) {
+//                 m_Syntax.SchemeName.CopyTo(0, chars, count, m_Syntax.SchemeName.Length);
+//                 count += m_Syntax.SchemeName.Length;
+//                 if (parts != UriComponents.Scheme) {
+//                     chars[count++] = ':';
+//                     if (InFact(Flags.AuthorityFound)) {
+//                         chars[count++] = '/';
+//                         chars[count++] = '/';
+//                     }
+//                 }
+//             }
+//
+//             //UserInfo
+//             if ((parts & UriComponents.UserInfo) != 0 && InFact(Flags.HasUserInfo))
+//             {
+//                 if ((nonCanonical & (ushort)UriComponents.UserInfo) != 0) {
+//                     switch (formatAs) {
+//                         case UriFormat.UriEscaped:
+//                             if (NotAny(Flags.UserEscaped))
+//                             {
+//                                 chars = UriHelper.EscapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, chars, 
+//                                     ref count, true, '?', '#', '%');
+//                             }
+//                             else {
+//                                 if (InFact(Flags.E_UserNotCanonical)) {
+//                                     // 
+//
+//                                 }
+//                                 m_String.CopyTo(m_Info.Offset.User, chars, count, m_Info.Offset.Host - m_Info.Offset.User);
+//                                 count += (m_Info.Offset.Host - m_Info.Offset.User);
+//                             }
+//                             break;
+//
+//                         case UriFormat.SafeUnescaped:
+//                             chars = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host - 1, 
+//                                 chars, ref count, '@', '/', '\\', InFact(Flags.UserEscaped) ? UnescapeMode.Unescape :
+//                                 UnescapeMode.EscapeUnescape, m_Syntax, false);
+//                             chars[count++] = '@';
+//                             break;
+//
+//                         case UriFormat.Unescaped:
+//                             chars = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, chars, 
+//                                 ref count, c_DummyChar, c_DummyChar, c_DummyChar, 
+//                                 UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, false);
+//                             break;
+//
+//                         default: //V1ToStringUnescape
+//                             chars = UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, chars, 
+//                                 ref count, c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, 
+//                                 false);
+//                             break;
+//                     }
+//                 }
+//                 else {
+//                     UriHelper.UnescapeString(m_String, m_Info.Offset.User, m_Info.Offset.Host, chars, ref count, 
+//                         c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, false);
+//                 }
+//                 if (parts == UriComponents.UserInfo)
+//                 {
+//                     //strip '@' delimiter
+//                     --count;
+//                 }
+//             }
+//
+//             // Host
+//             if ((parts & UriComponents.Host) != 0 && stemp.Length != 0)
+//             {
+//                 UnescapeMode mode;
+//                 if (formatAs != UriFormat.UriEscaped && HostType == Flags.BasicHostType 
+//                     && (nonCanonical & (ushort)UriComponents.Host) != 0) {
+//                     // only Basic host could be in the escaped form
+//                     mode = formatAs == UriFormat.Unescaped
+//                         ? (UnescapeMode.Unescape | UnescapeMode.UnescapeAll) :
+//                             (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape);
+//
+//                 }
+//                 else {
+//                     mode = UnescapeMode.CopyOnly;
+//                 }
+//                 // NormalizedHost
+//                 if ((parts & UriComponents.NormalizedHost) != 0)
+//                 {
+//                     unsafe
+//                     {
+//                         fixed (char* hostPtr = stemp)
+//                         {
+//                             bool allAscii = false;
+//                             bool atLeastOneValidIdn = false;
+//                             try
+//                             {
+//                                 // Upconvert any punycode to unicode, xn--pck -> ?
+//                                 stemp = DomainNameHelper.UnicodeEquivalent(
+//                                     hostPtr, 0, stemp.Length, ref allAscii, ref atLeastOneValidIdn);
+//                             }
+//                             // The host may be invalid punycode (www.xn--?-pck.com), 
+//                             // but we shouldn't throw after the constructor.
+//                             catch (UriFormatException) { }
+//                         }
+//                     }
+//                 }
+//                 chars = UriHelper.UnescapeString(stemp, 0, stemp.Length, chars, ref count, '/', '?', '#', mode, 
+//                     m_Syntax, false);
+//
+//                 // A fix up only for SerializationInfo and IpV6 host with a scopeID
+//                 if ((parts & UriComponents.SerializationInfoString) != 0 && HostType == Flags.IPv6HostType && 
+//                     (object)m_Info.ScopeId != null)
+//                 {
+//                     m_Info.ScopeId.CopyTo(0, chars, count-1, m_Info.ScopeId.Length);
+//                     count += m_Info.ScopeId.Length;
+//                     chars[count-1] = ']';
+//                 }
+//             }
+//
+//             //Port (always wants a ':' delimiter if got to this method)
+//             if ((parts & UriComponents.Port) != 0)
+//             {
+//                 if ((nonCanonical & (ushort)UriComponents.Port) == 0) {
+//                     //take it from m_String
+//                     if (InFact(Flags.NotDefaultPort)) {
+//                         ushort start = m_Info.Offset.Path;
+//                         while (m_String[--start] != ':') {
+//                             ;
+//                         }
+//                         m_String.CopyTo(start, chars, count, m_Info.Offset.Path - start);
+//                         count += (m_Info.Offset.Path - start);
+//                     }
+//                     else if ((parts & UriComponents.StrongPort) != 0 && m_Syntax.DefaultPort != UriParser.NoDefaultPort) {
+//                         chars[count++]= ':';
+//                         stemp = m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
+//                         stemp.CopyTo(0, chars, count, stemp.Length);
+//                         count += stemp.Length;
+//                     }
+//                 }
+//                 else if (InFact(Flags.NotDefaultPort) || ((parts & UriComponents.StrongPort) != 0 && 
+//                     m_Syntax.DefaultPort != UriParser.NoDefaultPort)) {
+//                     // recreate string from port value
+//                     chars[count++]= ':';
+//                     stemp = m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
+//                     stemp.CopyTo(0, chars, count, stemp.Length);
+//                     count += stemp.Length;
+//                 }
+//             }
+//
+//             ushort delimiterAwareIndex;
+//
+//             //Path
+//             if ((parts & UriComponents.Path) != 0)
+//             {
+//                 chars = GetCanonicalPath(chars, ref count, formatAs);
+//
+//                 // (possibly strip the leading '/' delimiter)
+//                 if (parts == UriComponents.Path)
+//                 {
+//                     if (InFact(Flags.AuthorityFound) && count !=0 && chars[0] == '/')
+//                     {
+//                         delimiterAwareIndex = 1; --count;
+//                     }
+//                     else
+//                     {
+//                         delimiterAwareIndex = 0;
+//                     }
+//                     return count == 0? string.Empty: new string(chars, delimiterAwareIndex, count);
+//                 }
+//             }
+//
+//             //Query (possibly strip the '?' delimiter)
+//             if ((parts & UriComponents.Query) != 0 && m_Info.Offset.Query < m_Info.Offset.Fragment)
+//             {
+//                 delimiterAwareIndex = (ushort)(m_Info.Offset.Query+1);
+//                 if(parts != UriComponents.Query)
+//                     chars[count++] = '?';   //see Fragment+1 below
+//
+//                 if ((nonCanonical & (ushort)UriComponents.Query) != 0)
+//                 {
+//                     switch (formatAs)
+//                     {
+//                     case UriFormat.UriEscaped:
+//                         //Can Assert IsImplicitfile == false
+//                         if (NotAny(Flags.UserEscaped))
+//                             chars = UriHelper.EscapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
+//                                 ref count, true, '#', c_DummyChar, '%');
+//                         else
+//                         {
+//                             // 
+//
+//
+//                             UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
+//                                 ref count, c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, 
+//                                 true);
+//                         }
+//                         break;
+//
+//                     case V1ToStringUnescape:
+//
+//                         chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
+//                             ref count, '#', c_DummyChar, c_DummyChar, (InFact(Flags.UserEscaped) ?
+//                             UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) | UnescapeMode.V1ToStringFlag, 
+//                             m_Syntax, true);
+//                         break;
+//
+//                     case UriFormat.Unescaped:
+//
+//                         chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
+//                             ref count, '#', c_DummyChar, c_DummyChar, 
+//                             (UnescapeMode.Unescape | UnescapeMode.UnescapeAll), m_Syntax, true);
+//                         break;
+//
+//                     default: // UriFormat.SafeUnescaped
+//
+//                         chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, 
+//                             ref count, '#', c_DummyChar, c_DummyChar, (InFact(Flags.UserEscaped) ?
+//                             UnescapeMode.Unescape : UnescapeMode.EscapeUnescape), m_Syntax, true);
+//                         break;
+//                     }
+//                 }
+//                 else
+//                 {
+//                     UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.Fragment, chars, ref count, 
+//                         c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, true);
+//                 }
+//             }
+//
+//             //Fragment (possibly strip the '#' delimiter)
+//             if ((parts & UriComponents.Fragment) != 0 && m_Info.Offset.Fragment < m_Info.Offset.End)
+//             {
+//                 delimiterAwareIndex = (ushort)(m_Info.Offset.Fragment+1);
+//                 if(parts != UriComponents.Fragment)
+//                     chars[count++] = '#';   //see Fragment+1 below
+//
+//                 if ((nonCanonical & (ushort)UriComponents.Fragment) != 0)
+//                 {
+//                     switch (formatAs) {
+//                     case UriFormat.UriEscaped:
+//                             if (NotAny(Flags.UserEscaped))
+//                                 chars = UriHelper.EscapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars,
+//                                     ref count, true, UriParser.ShouldUseLegacyV2Quirks ? '#' : c_DummyChar, c_DummyChar, '%');
+//                             else
+//                             {
+//                                 // 
+//
+//
+//                                 UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, 
+//                                     ref count, c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, 
+//                                     false);
+//                             }
+//                             break;
+//
+//                     case V1ToStringUnescape:
+//
+//                             chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, 
+//                                 ref count, '#', c_DummyChar, c_DummyChar, (InFact(Flags.UserEscaped) ?
+//                                 UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) | UnescapeMode.V1ToStringFlag, 
+//                                 m_Syntax, false);
+//                         break;
+//                     case UriFormat.Unescaped:
+//
+//                         chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, 
+//                             ref count, '#', c_DummyChar, c_DummyChar, 
+//                             UnescapeMode.Unescape | UnescapeMode.UnescapeAll, m_Syntax, false);
+//                         break;
+//
+//                     default: // UriFormat.SafeUnescaped
+//
+//                         chars = UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, 
+//                             ref count, '#', c_DummyChar, c_DummyChar, (InFact(Flags.UserEscaped) ?
+//                             UnescapeMode.Unescape : UnescapeMode.EscapeUnescape), m_Syntax, false);
+//                         break;
+//                     }
+//                 }
+//                 else
+//                 {
+//                     UriHelper.UnescapeString(m_String, delimiterAwareIndex, m_Info.Offset.End, chars, ref count, 
+//                         c_DummyChar, c_DummyChar, c_DummyChar, UnescapeMode.CopyOnly, m_Syntax, false);
+//                 }
+//             }
+//
+//             return new string(chars, 0, count);
+//         }
+//
+//         //
+//         // This method is called only if the user string has a canonical representation
+//         // of requested parts
+//         //
+//         private string GetUriPartsFromUserString(UriComponents uriParts) {
+//
+//             ushort delimiterAwareIdx;
+//
+//             switch (uriParts & ~UriComponents.KeepDelimiter) {
+//                     // For FindServicePoint perf
+//                 case UriComponents.Scheme | UriComponents.Host | UriComponents.Port:
+//                     if (!InFact(Flags.HasUserInfo))
+//                         return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Path - m_Info.Offset.Scheme);
+//
+//                     return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme)
+//                          + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host);
+//
+//                     // For HttpWebRequest.ConnectHostAndPort perf
+//                 case UriComponents.HostAndPort:  //Host|StrongPort
+//
+//                     if (!InFact(Flags.HasUserInfo))
+//                         goto case UriComponents.StrongAuthority;
+//
+//                     if (InFact(Flags.NotDefaultPort) || m_Syntax.DefaultPort == UriParser.NoDefaultPort)
+//                         return m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host);
+//
+//                     return m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Path - m_Info.Offset.Host)
+//                         + ':' + m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
+//
+//                     // For an obvious common case perf
+//                 case UriComponents.AbsoluteUri:     //Scheme|UserInfo|Host|Port|Path|Query|Fragment,
+//                     if (m_Info.Offset.Scheme == 0 && m_Info.Offset.End == m_String.Length)
+//                         return m_String;
+//
+//                     return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.End - m_Info.Offset.Scheme);
+//
+//                     // For Uri.Equals() and HttpWebRequest through a proxy perf
+//                 case UriComponents.HttpRequestUrl:   //Scheme|Host|Port|Path|Query,
+//                     if (InFact(Flags.HasUserInfo)) {
+//                         return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme)
+//                             + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.Fragment - m_Info.Offset.Host);
+//                     }
+//                     if (m_Info.Offset.Scheme == 0 && m_Info.Offset.Fragment == m_String.Length)
+//                         return m_String;
+//
+//                     return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Fragment - m_Info.Offset.Scheme);
+//
+//                     // For CombineUri() perf
+//                 case UriComponents.SchemeAndServer|UriComponents.UserInfo:
+//                     return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Path - m_Info.Offset.Scheme);
+//
+//                     // For Cache perf
+//                 case (UriComponents.AbsoluteUri & ~UriComponents.Fragment):
+//                     if (m_Info.Offset.Scheme == 0 && m_Info.Offset.Fragment == m_String.Length)
+//                         return m_String;
+//
+//                     return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.Fragment - m_Info.Offset.Scheme);
+//
+//
+//                 // Strip scheme delimiter if was not requested
+//                 case UriComponents.Scheme:
+//                         if (uriParts != UriComponents.Scheme)
+//                             return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme);
+//
+//                         return m_Syntax.SchemeName;
+//
+//                 // KeepDelimiter makes no sense for this component
+//                 case UriComponents.Host:
+//                     ushort idx = m_Info.Offset.Path;
+//                     if (InFact(Flags.NotDefaultPort|Flags.PortNotCanonical)) {
+//                         //Means we do have ':' after the host
+//                         while (m_String[--idx] != ':')
+//                             ;
+//                     }
+//                     return (idx - m_Info.Offset.Host == 0)? string.Empty: m_String.Substring(m_Info.Offset.Host, 
+//                         idx - m_Info.Offset.Host);
+//
+//                 case UriComponents.Path:
+//
+//                     // Strip the leading '/' for a hierarchical URI if no delimiter was requested
+//                     if (uriParts == UriComponents.Path && InFact(Flags.AuthorityFound) &&
+//                         m_Info.Offset.End > m_Info.Offset.Path && m_String[m_Info.Offset.Path] == '/')
+//                         delimiterAwareIdx = (ushort)(m_Info.Offset.Path + 1);
+//                     else
+//                         delimiterAwareIdx = m_Info.Offset.Path;
+//
+//                     if (delimiterAwareIdx >= m_Info.Offset.Query)
+//                         return string.Empty;
+//
+//
+//                     return m_String.Substring(delimiterAwareIdx, m_Info.Offset.Query - delimiterAwareIdx);
+//
+//                 case UriComponents.Query:
+//                     // Strip the '?' if no delimiter was requested
+//                     if (uriParts == UriComponents.Query)
+//                         delimiterAwareIdx = (ushort)(m_Info.Offset.Query + 1);
+//                     else
+//                         delimiterAwareIdx = m_Info.Offset.Query;
+//
+//                     if (delimiterAwareIdx >= m_Info.Offset.Fragment)
+//                         return string.Empty;
+//
+//                     return m_String.Substring(delimiterAwareIdx, m_Info.Offset.Fragment - delimiterAwareIdx);
+//
+//                 case UriComponents.Fragment:
+//                     // Strip the '#' if no delimiter was requested
+//                     if (uriParts == UriComponents.Fragment)
+//                         delimiterAwareIdx = (ushort)(m_Info.Offset.Fragment + 1);
+//                     else
+//                         delimiterAwareIdx = m_Info.Offset.Fragment;
+//
+//                     if (delimiterAwareIdx >= m_Info.Offset.End)
+//                         return string.Empty;
+//
+//                     return m_String.Substring(delimiterAwareIdx, m_Info.Offset.End - delimiterAwareIdx);
+//
+//                 case UriComponents.UserInfo | UriComponents.Host | UriComponents.Port:
+//                     return (m_Info.Offset.Path - m_Info.Offset.User == 0) ? string.Empty : 
+//                         m_String.Substring(m_Info.Offset.User, m_Info.Offset.Path - m_Info.Offset.User);
+//
+//                 case UriComponents.StrongAuthority:  //UserInfo|Host|StrongPort
+//                     if (InFact(Flags.NotDefaultPort) || m_Syntax.DefaultPort == UriParser.NoDefaultPort)
+//                         goto case UriComponents.UserInfo | UriComponents.Host | UriComponents.Port;
+//
+//                     return m_String.Substring(m_Info.Offset.User, m_Info.Offset.Path - m_Info.Offset.User)
+//                         + ':' + m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
+//
+//                 case UriComponents.PathAndQuery:        //Path|Query,
+//                     return m_String.Substring(m_Info.Offset.Path, m_Info.Offset.Fragment - m_Info.Offset.Path);
+//
+//                 case UriComponents.HttpRequestUrl|UriComponents.Fragment: //Scheme|Host|Port|Path|Query|Fragment,
+//                     if (InFact(Flags.HasUserInfo)) {
+//                         return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.User - m_Info.Offset.Scheme)
+//                             + m_String.Substring(m_Info.Offset.Host, m_Info.Offset.End - m_Info.Offset.Host);
+//                     }
+//                     if (m_Info.Offset.Scheme == 0 && m_Info.Offset.End == m_String.Length)
+//                         return m_String;
+//
+//                     return m_String.Substring(m_Info.Offset.Scheme, m_Info.Offset.End - m_Info.Offset.Scheme);
+//
+//                 case UriComponents.PathAndQuery|UriComponents.Fragment:  //LocalUrl|Fragment
+//                     return m_String.Substring(m_Info.Offset.Path, m_Info.Offset.End - m_Info.Offset.Path);
+//
+//                 case UriComponents.UserInfo:
+//                         // Strip the '@' if no delimiter was requested
+//
+//                     if (NotAny(Flags.HasUserInfo))
+//                         return string.Empty;
+//
+//                     if (uriParts == UriComponents.UserInfo)
+//                         delimiterAwareIdx = (ushort)(m_Info.Offset.Host - 1);
+//                     else
+//                         delimiterAwareIdx = m_Info.Offset.Host;
+//
+//                     if (m_Info.Offset.User >= delimiterAwareIdx)
+//                         return string.Empty;
+//
+//                     return m_String.Substring(m_Info.Offset.User, delimiterAwareIdx - m_Info.Offset.User);
+//
+//                 default:
+//                     return null;
+//             }
+//         }
+//
+//
+//         //
+//         //This method does:
+//         //  - Creates m_Info member
+//         //  - checks all componenets up to path on their canonical representation
+//         //  - continues parsing starting the path position
+//         //  - Sets the offsets of remaining components
+//         //  - Sets the Canonicalization flags if applied
+//         //  - Will NOT create MoreInfo members
+//         //
+//         private unsafe void ParseRemaining() {
+//
+//             // ensure we parsed up to the path
+//             EnsureUriInfo();
+//
+//             Flags cF = Flags.Zero;
+//
+//             if (UserDrivenParsing)
+//                 goto Done;
+//
+//             // Do we have to continue building Iri'zed string from original string
+//             bool buildIriStringFromPath = m_iriParsing && ((m_Flags & Flags.HasUnicode) != 0) && ((m_Flags & Flags.RestUnicodeNormalized) == 0);
+//
+//             ushort origIdx;     // stores index to switched original string
+//             ushort idx = m_Info.Offset.Scheme;
+//             ushort length = (ushort)m_String.Length;
+//             Check result = Check.None;
+//             UriSyntaxFlags syntaxFlags = m_Syntax.Flags;    // perf
+//
+//             // Multithreading!
+//             // m_Info.Offset values may be parsed twice but we lock only on m_Flags update.
+//
+//             fixed (char* str = m_String){
+//                 // Cut trailing spaces in m_String
+//                 if (length > idx && IsLWS(str[length - 1]))
+//                 {
+//                     --length;
+//                     while (length != idx && IsLWS(str[--length]))
+//                         ;
+//                     ++length;
+//                 }
+//
+//                 if (IsImplicitFile){
+//                     cF |= Flags.SchemeNotCanonical;
+//                 }
+//                 else {
+//                     ushort i = 0;
+//                     ushort syntaxLength = (ushort)m_Syntax.SchemeName.Length;
+//                     for (; i < syntaxLength; ++i)
+//                     {
+//                         if (m_Syntax.SchemeName[i] != str[idx + i])
+//                             cF |= Flags.SchemeNotCanonical;
+//                     }
+//                     // For an authority Uri only // after the scheme would be canonical
+//                     // (compatibility bug http:\\host)
+//                     if (((m_Flags & Flags.AuthorityFound) != 0) && (idx + i + 3 >= length || str[idx + i + 1] != '/' || 
+//                         str[idx + i + 2] != '/')) 
+//                     {
+//                         cF |= Flags.SchemeNotCanonical;
+//                     }
+//                 }
+//
+//
+//                 //Check the form of the user info
+//                 if ((m_Flags & Flags.HasUserInfo) != 0){
+//                     idx = m_Info.Offset.User;
+//                     result = CheckCanonical(str, ref idx, m_Info.Offset.Host, '@');
+//                     if ((result & Check.DisplayCanonical) == 0){
+//                         cF |= Flags.UserNotCanonical;
+//                     }
+//                     if ((result & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical){
+//                         cF |= Flags.E_UserNotCanonical;
+//                     }
+//                     if (m_iriParsing && ((result & (Check.DisplayCanonical | Check.EscapedCanonical | Check.BackslashInPath
+//                                                     | Check.FoundNonAscii | Check.NotIriCanonical))
+//                                                     == (Check.DisplayCanonical | Check.FoundNonAscii))){
+//                         cF |= Flags.UserIriCanonical;
+//                     }
+//                 }
+//             }
+//             //
+//             // Delay canonical Host checking to avoid creation of a host string
+//             // Will do that on demand.
+//             //
+//
+//
+//             //
+//             //We have already checked on the port in EnsureUriInfo() that calls CreateUriInfo
+//             //
+//
+//             //
+//             // Parsing the Path if any
+//             //
+//
+//             // For iri parsing if we found unicode the idx has offset into m_orig string..
+//             // so restart parsing from there and make m_Info.Offset.Path as m_string.length
+//
+//             idx = m_Info.Offset.Path;
+//             origIdx = m_Info.Offset.Path;
+//
+//             //Some uris do not have a query
+//             //    When '?' is passed as delimiter, then it's special case
+//             //    so both '?' and '#' will work as delimiters
+//             if (buildIriStringFromPath){
+//
+//                 // Dos paths have no host.  Other schemes cleared/set m_String with host information in PrivateParseMinimal.
+//                 if (IsDosPath) {
+//                     if (IsImplicitFile) {
+//                         m_String = String.Empty;
+//                     }
+//                     else {
+//                         m_String = m_Syntax.SchemeName + SchemeDelimiter;
+//                     }
+//                 }
+//
+//                 m_Info.Offset.Path = (ushort)m_String.Length;
+//                 idx = m_Info.Offset.Path;
+//
+//                 ushort offset = origIdx;
+//                 if (IsImplicitFile || ((syntaxFlags & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) == 0)){
+//                     FindEndOfComponent(m_originalUnicodeString, ref origIdx, (ushort)m_originalUnicodeString.Length, c_DummyChar);
+//                 }
+//                 else{
+//                     FindEndOfComponent(m_originalUnicodeString, ref origIdx, (ushort)m_originalUnicodeString.Length,
+//                    (m_Syntax.InFact(UriSyntaxFlags.MayHaveQuery) ? '?' : m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment) ? '#' : c_EOL));
+//                 }
+//
+//                 // Correctly escape unescape
+//                 string escapedPath = EscapeUnescapeIri(m_originalUnicodeString, offset, origIdx, UriComponents.Path);
+//
+//                 // Normalize path
+//                 try{
+//                     if (UriParser.ShouldUseLegacyV2Quirks)
+//                         m_String += escapedPath.Normalize(NormalizationForm.FormC);
+//                     else
+//                         m_String += escapedPath;
+//                 }
+//                 catch (ArgumentException){
+//                     UriFormatException e = GetException(ParsingError.BadFormat);
+//                     throw e;
+//                 }
+//
+//                 if (!ServicePointManager.AllowAllUriEncodingExpansion && m_String.Length > ushort.MaxValue){
+//                     UriFormatException e = GetException(ParsingError.SizeLimit);
+//                     throw e;
+//                 }
+//
+//                 length = (ushort)m_String.Length;
+//             }
+//
+//             fixed (char* str = m_String){
+//                 if (IsImplicitFile || ((syntaxFlags & (UriSyntaxFlags.MayHaveQuery | UriSyntaxFlags.MayHaveFragment)) == 0)){
+//                     result = CheckCanonical(str, ref idx, length, c_DummyChar);
+//                 }
+//                 else {
+//                     result = CheckCanonical(str, ref idx, length, (((syntaxFlags & UriSyntaxFlags.MayHaveQuery) != 0) 
+//                         ? '?' : m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment) ? '#' : c_EOL));
+//                 }
+//
+//                 // ATTN:
+//                 // This may render problems for unknown schemes, but in general for an authority based Uri
+//                 // (that has slashes) a path should start with "/"
+//                 // This becomes more interesting knowning how a file uri is used in "file://c:/path"
+//                 // It will be converted to file:///c:/path
+//                 //
+//                 // However, even more interesting is that vsmacros://c:\path will not add the third slash in the _canoical_ case
+//                 // (vsmacros inventors have violated the RFC)
+//                 //
+//                 // We use special syntax flag to check if the path is rooted, i.e. has a first slash
+//                 //
+//                 if (((m_Flags & Flags.AuthorityFound) != 0) && ((syntaxFlags & UriSyntaxFlags.PathIsRooted) != 0)
+//                     && (m_Info.Offset.Path == length || (str[m_Info.Offset.Path] != '/' && str[m_Info.Offset.Path] != '\\'))){
+//                     cF |= Flags.FirstSlashAbsent;
+//                 }
+//             }
+//             // Check the need for compression or backslashes conversion
+//             // we included IsDosPath since it may come with other than FILE uri, for ex. scheme://C:\path
+//             // (This is very unfortunate that the original design has included that feature)
+//             bool nonCanonical = false;
+//             if (IsDosPath || (((m_Flags & Flags.AuthorityFound) != 0) &&
+//                 (((syntaxFlags & (UriSyntaxFlags.CompressPath | UriSyntaxFlags.ConvertPathSlashes)) != 0) ||
+//                 m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes))))
+//             {
+//                 if (((result & Check.DotSlashEscaped) != 0) && m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes))
+//                 {
+//                     cF |= (Flags.E_PathNotCanonical | Flags.PathNotCanonical);
+//                     nonCanonical = true;
+//                 }
+//
+//                 if (((syntaxFlags & (UriSyntaxFlags.ConvertPathSlashes)) != 0) && (result & Check.BackslashInPath) != 0){
+//                     cF |= (Flags.E_PathNotCanonical | Flags.PathNotCanonical);
+//                     nonCanonical = true;
+//                 }
+//
+//                 if (((syntaxFlags & (UriSyntaxFlags.CompressPath)) != 0) && ((cF & Flags.E_PathNotCanonical) != 0 ||
+//                     (result & Check.DotSlashAttn) != 0)) 
+//                 {
+//                     cF |= Flags.ShouldBeCompressed;
+//                 }
+//
+//                 if ((result & Check.BackslashInPath) != 0)
+//                     cF |= Flags.BackslashInPath;
+//
+//             }
+//             else if ((result & Check.BackslashInPath) != 0){
+//                 // for a "generic" path '\' should be escaped
+//                 cF |= Flags.E_PathNotCanonical;
+//                 nonCanonical = true;
+//             }
+//
+//             if ((result & Check.DisplayCanonical) == 0){
+//                 // For implicit file the user string is usually in perfect display format,
+//                 // Hence, ignoring complains from CheckCanonical()
+//                 //
+//
+//                 if (((m_Flags & Flags.ImplicitFile) == 0) || ((m_Flags & Flags.UserEscaped) != 0) || 
+//                     (result & Check.ReservedFound) != 0) {
+//                     //means it's found as escaped or has unescaped Reserved Characters
+//                     cF |= Flags.PathNotCanonical;
+//                     nonCanonical = true;
+//                 }
+//             }
+//
+//             if (((m_Flags & Flags.ImplicitFile) != 0) && (result & (Check.ReservedFound | Check.EscapedCanonical)) != 0){
+//                 // need to escape reserved chars or re-escape '%' if an "escaped sequence" was found
+//                 result &= ~Check.EscapedCanonical;
+//             }
+//
+//             if ((result & Check.EscapedCanonical) == 0){
+//                 //means it's found as not completely escaped
+//                 cF |= Flags.E_PathNotCanonical;
+//             }
+//
+//             if (m_iriParsing && !nonCanonical & ((result & (Check.DisplayCanonical | Check.EscapedCanonical
+//                             | Check.FoundNonAscii | Check.NotIriCanonical))
+//                             == (Check.DisplayCanonical | Check.FoundNonAscii))){
+//                 cF |= Flags.PathIriCanonical;
+//             }
+//
+//             //
+//             //Now we've got to parse the Query if any. Note that Query requires the presence of '?'
+//             //
+//            if (buildIriStringFromPath){
+//                ushort offset = origIdx;
+//
+//                if (origIdx < m_originalUnicodeString.Length && m_originalUnicodeString[origIdx] == '?'){
+//                    ++origIdx; // This is to exclude first '?' character from checking
+//                    FindEndOfComponent(m_originalUnicodeString, ref origIdx, (ushort)m_originalUnicodeString.Length, ((syntaxFlags &(UriSyntaxFlags.MayHaveFragment)) != 0) ? '#' : c_EOL);
+//
+//                    // Correctly escape unescape
+//                    string escapedPath = EscapeUnescapeIri(m_originalUnicodeString, offset, origIdx, UriComponents.Query);
+//
+//                    // Normalize path
+//                    try{
+//                        if (UriParser.ShouldUseLegacyV2Quirks)
+//                            m_String += escapedPath.Normalize(NormalizationForm.FormC);
+//                        else
+//                            m_String += escapedPath;
+//                    }
+//                    catch (ArgumentException){
+//                        UriFormatException e = GetException(ParsingError.BadFormat);
+//                        throw e;
+//                    }
+//
+//                    if (!ServicePointManager.AllowAllUriEncodingExpansion && m_String.Length > ushort.MaxValue){
+//                        UriFormatException e = GetException(ParsingError.SizeLimit);
+//                        throw e;
+//                    }
+//
+//                    length = (ushort)m_String.Length;
+//                }
+//             }
+//
+//             m_Info.Offset.Query = idx;
+//
+//             fixed (char* str = m_String){
+//                 if (idx < length && str[idx] == '?'){
+//                     ++idx; // This is to exclude first '?' character from checking
+//                     result = CheckCanonical(str, ref idx, length, ((syntaxFlags & (UriSyntaxFlags.MayHaveFragment)) != 0) 
+//                         ? '#' : c_EOL);
+//                     if ((result & Check.DisplayCanonical) == 0){
+//                         cF |= Flags.QueryNotCanonical;
+//                     }
+//
+//                     if ((result & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical){
+//                         cF |= Flags.E_QueryNotCanonical;
+//                     }
+//
+//                     if (m_iriParsing && ((result & (Check.DisplayCanonical | Check.EscapedCanonical | Check.BackslashInPath
+//                                 | Check.FoundNonAscii | Check.NotIriCanonical))
+//                                 == (Check.DisplayCanonical | Check.FoundNonAscii))){
+//                         cF |= Flags.QueryIriCanonical;
+//                     }
+//
+//                 }
+//             }
+//             //
+//             //Now we've got to parse the Fragment if any. Note that Fragment requires the presense of '#'
+//             //
+//             if (buildIriStringFromPath){
+//                 ushort offset = origIdx;
+//
+//                 if (origIdx < m_originalUnicodeString.Length && m_originalUnicodeString[origIdx] == '#')
+//                 {
+//                     ++origIdx; // This is to exclude first '#' character from checking
+//                     FindEndOfComponent(m_originalUnicodeString, ref origIdx, (ushort)m_originalUnicodeString.Length, c_EOL);
+//
+//                     // Correctly escape unescape
+//                     string escapedPath = EscapeUnescapeIri(m_originalUnicodeString, offset, origIdx, UriComponents.Fragment);
+//
+//                     // Normalize path
+//                     try{
+//                         if (UriParser.ShouldUseLegacyV2Quirks)
+//                             m_String += escapedPath.Normalize(NormalizationForm.FormC);
+//                         else
+//                             m_String += escapedPath;
+//                     }
+//                     catch (ArgumentException){
+//                         UriFormatException e = GetException(ParsingError.BadFormat);
+//                         throw e;
+//                     }
+//
+//                     if (!ServicePointManager.AllowAllUriEncodingExpansion && m_String.Length > ushort.MaxValue){
+//                         UriFormatException e = GetException(ParsingError.SizeLimit);
+//                         throw e;
+//                     }
+//
+//                     length = (ushort)m_String.Length;
+//                 }
+//             }
+//
+//             m_Info.Offset.Fragment = idx;
+//
+//             fixed (char* str = m_String){
+//                 if (idx < length && str[idx] == '#'){
+//                     ++idx; // This is to exclude first '#' character from checking
+//                     //We don't using c_DummyChar since want to allow '?' and '#' as unescaped
+//                     result = CheckCanonical(str, ref idx, length, c_EOL);
+//                     if ((result & Check.DisplayCanonical) == 0){
+//                         cF |= Flags.FragmentNotCanonical;
+//                     }
+//
+//                     if ((result & (Check.EscapedCanonical | Check.BackslashInPath)) != Check.EscapedCanonical){
+//                         cF |= Flags.E_FragmentNotCanonical;
+//                     }
+//
+//                     if (m_iriParsing && ((result & (Check.DisplayCanonical | Check.EscapedCanonical | Check.BackslashInPath
+//                                 | Check.FoundNonAscii | Check.NotIriCanonical))
+//                                 == (Check.DisplayCanonical | Check.FoundNonAscii))){
+//                         cF |= Flags.FragmentIriCanonical;
+//                     }
+//
+//                 }
+//             }
+//                 m_Info.Offset.End = idx;
+//         Done:
+//
+//             cF |= Flags.AllUriInfoSet;
+//             lock (m_Info)
+//             {
+//                 m_Flags |= cF;
+//             }
+//             m_Flags |= Flags.RestUnicodeNormalized;
+//         }
+//
+//         //
+//         //
+//         // verifies the syntax of the scheme part
+//         // Checks on implicit File: scheme due to simple Dos/Unc path passed
+//         // returns the start of the next component  position
+//         // throws UriFormatException if invalid scheme
+//         //
+//         unsafe static private ushort ParseSchemeCheckImplicitFile(char *uriString, ushort length, 
+//             ref ParsingError err, ref Flags flags, ref UriParser syntax) {
+//
+//             ushort idx = 0;
+//
+//             //skip whitespaces
+//             while(idx < length && IsLWS(uriString[idx])) {
+//                 ++idx;
+//             }
+//
+//             // sets the recognizer for well known registered schemes
+//             // file, ftp, http, https, uuid, etc
+//             // Note that we don't support one-letter schemes that will be put into a DOS path bucket
+//
+//             // 
+//             ushort end = idx;
+//             while (end < length && uriString[end] != ':') {
+//                 ++end;
+//             }
+//
+//             // NB: On 64-bits we will use less optimized code from CheckSchemeSyntax()
+//             //
+//             if (IntPtr.Size == 4) {
+//                 // long = 4chars: The minimal size of a known scheme is 2 + ':'
+//                 if (end != length && end >= idx+2 && 
+//                     CheckKnownSchemes((long*) (uriString + idx), (ushort)(end-idx), ref syntax)) {
+//                     return (ushort)(end+1);
+//                 }
+//             }
+//
+//             //NB: A string must have at least 3 characters and at least 1 before ':'
+//             if (idx+2 >= length || end == idx) {
+//                 err = ParsingError.BadFormat;
+//                 return 0;
+//             }
+//
+//             //Check for supported special cases like a DOS file path OR a UNC share path
+//             //NB: A string may not have ':' if this is a UNC path
+//         {
+//             char c;
+//             if ((c=uriString[idx+1]) == ':' || c == '|') {
+// #if !PLATFORM_UNIX
+//                 //DOS-like path?
+//                 if (IsAsciiLetter(uriString[idx])) {
+//                     if((c=uriString[idx+2]) == '\\' || c== '/') {
+//                         flags |= (Flags.DosPath|Flags.ImplicitFile|Flags.AuthorityFound);
+//                         syntax = UriParser.FileUri;
+//                         return idx;
+//                     }
+//                     err = ParsingError.MustRootedPath;
+//                     return 0;
+//                 }
+// #endif // !PLATFORM_UNIX
+//                 if (c == ':')
+//                     err = ParsingError.BadScheme;
+//                 else
+//                     err = ParsingError.BadFormat;
+//                 return 0;
+//             }
+// #if !PLATFORM_UNIX
+//             else if ((c=uriString[idx]) == '/' || c == '\\') {
+//                 //UNC share ?
+//                 if ((c=uriString[idx+1]) == '\\' || c == '/') {
+//                     flags |= (Flags.UncPath|Flags.ImplicitFile|Flags.AuthorityFound);
+//                     syntax = UriParser.FileUri;
+//                     idx+=2;
+//                     // V1.1 compat this will simply eat any slashes prepended to a UNC path
+//                     while (idx < length && ((c=uriString[idx]) == '/' ||  c == '\\'))
+//                         ++idx;
+//
+//                     return idx;
+//                 }
+//                 err = ParsingError.BadFormat;
+//                 return 0;
+//             }
+// #else
+//             else if (uriString[idx] == '/') {
+//                 // On UNIX an implicit file has the form /<path> or scheme:///<path>
+//                 if (idx == 0 || uriString[idx-1] != ':' ) {
+//                     // No scheme present; implicit /<path> starting at idx
+//                     flags |= (Flags.ImplicitFile|Flags.AuthorityFound);
+//                     syntax = UriParser.FileUri;
+//                     return idx;
+//                 } else if (uriString[idx+1] == '/' && uriString[idx+2] == '/') {
+//                     // scheme present; rooted path starts at idx + 2
+//                     flags |= (Flags.ImplicitFile|Flags.AuthorityFound);
+//                     syntax = UriParser.FileUri;
+//                     idx+=2;
+//                     return idx;
+//                 }
+//             }
+//             else if (uriString[idx] == '\\') {
+//                 err = ParsingError.BadFormat;
+//                 return 0;
+//             }
+// #endif // !PLATFORM_UNIX
+//         }
+//
+//             if (end == length) {
+//                 err = ParsingError.BadFormat;
+//                 return 0;
+//             }
+//
+//             // Here could be a possibly valid, and not well-known scheme
+//             // Finds the scheme delimiter
+//             // we don;t work with the schemes names > c_MaxUriSchemeName (should be ~1k)
+//             if ((end-idx) > c_MaxUriSchemeName) {
+//                 err = ParsingError.SchemeLimit;
+//                 return 0;
+//             }
+//
+//             //Check the syntax, canonicalize  and avoid a GC call
+//             char* schemePtr = stackalloc char[end-idx];
+//             for (length = 0; idx < end; ++idx) {
+//                 schemePtr[length++] = uriString[idx];
+//             }
+//             err = CheckSchemeSyntax(schemePtr, length, ref syntax);
+//             if (err != ParsingError.None) {
+//                 return 0;
+//             }
+//             return (ushort)(end+1);
+//         }
+//         //
+//         // Quickly parses well known schemes.
+//         // nChars does not include the last ':'. Assuming there is one at the end of passed buffer
+//         unsafe static private bool CheckKnownSchemes(long *lptr, ushort nChars, ref UriParser syntax) {
+//             //NOTE beware of too short input buffers!
+//
+//             const long _HTTP_Mask0   = 'h'|('t'<<16)|((long)'t'<<32)|((long)'p'<<48);
+//             const char _HTTPS_Mask1  = 's';
+//             const int  _WS_Mask      = 'w'|('s'<<16);
+//             const long _WSS_Mask     = 'w'|('s'<<16)|((long)'s'<<32)|((long)':'<<48);
+//             const long _FTP_Mask     = 'f'|('t'<<16)|((long)'p'<<32)|((long)':'<<48);
+//             const long _FILE_Mask0   = 'f'|('i'<<16)|((long)'l'<<32)|((long)'e'<<48);
+//             const long _GOPHER_Mask0 = 'g'|('o'<<16)|((long)'p'<<32)|((long)'h'<<48);
+//             const int  _GOPHER_Mask1 = 'e'|('r'<<16);
+//             const long _MAILTO_Mask0 = 'm'|('a'<<16)|((long)'i'<<32)|((long)'l'<<48);
+//             const int  _MAILTO_Mask1 = 't'|('o'<<16);
+//             const long _NEWS_Mask0   = 'n'|('e'<<16)|((long)'w'<<32)|((long)'s'<<48);
+//             const long _NNTP_Mask0   = 'n'|('n'<<16)|((long)'t'<<32)|((long)'p'<<48);
+//             const long _UUID_Mask0   = 'u'|('u'<<16)|((long)'i'<<32)|((long)'d'<<48);
+//
+//             const long _TELNET_Mask0 = 't'|('e'<<16)|((long)'l'<<32)|((long)'n'<<48);
+//             const int  _TELNET_Mask1 = 'e'|('t'<<16);
+//
+//             const long _NETXXX_Mask0 = 'n'|('e'<<16)|((long)'t'<<32)|((long)'.'<<48);
+//             const long _NETTCP_Mask1 = 't'|('c'<<16)|((long)'p'<<32)|((long)':'<<48);
+//             const long _NETPIPE_Mask1 = 'p'|('i'<<16)|((long)'p'<<32)|((long)'e'<<48);
+//
+//             const long _LDAP_Mask0   = 'l'|('d'<<16)|((long)'a'<<32)|((long)'p'<<48);
+//
+//
+//             const long _LOWERCASE_Mask = 0x0020002000200020L;
+//             const int  _INT_LOWERCASE_Mask = 0x00200020;
+//
+//             if (nChars == 2) {
+//                 // This is the only known scheme of length 2
+//                 if ((((int)*lptr) | _INT_LOWERCASE_Mask) == _WS_Mask) {
+//                     syntax = UriParser.WsUri;
+//                     return true;
+//                 }
+//                 return false;
+//             }
+//
+//             //Map to a known scheme if possible
+//             //upgrade 4 letters to ASCII lower case, keep a false case to stay false
+//             switch (*lptr | _LOWERCASE_Mask) {
+//                 case _HTTP_Mask0:
+//                     if (nChars == 4) {
+//                         syntax = UriParser.HttpUri;
+//                         return true;
+//                     }
+//                     if (nChars == 5 && ((*(char*)(lptr+1))|0x20) == _HTTPS_Mask1) {
+//                         syntax = UriParser.HttpsUri;
+//                         return true;
+//                     }
+//                     break;
+//                 case _WSS_Mask:
+//                     if (nChars == 3)
+//                     {
+//                         syntax = UriParser.WssUri;
+//                         return true;
+//                     }
+//                     break;
+//                 case _FILE_Mask0:
+//                     if (nChars == 4) {
+//                         syntax = UriParser.FileUri;
+//                         return true;
+//                     }
+//                     break;
+//                 case _FTP_Mask:
+//                     if (nChars == 3) {
+//                         syntax = UriParser.FtpUri;
+//                         return true;
+//                     }
+//                     break;
+//
+//                 case _NEWS_Mask0:
+//                     if (nChars == 4) {
+//                         syntax = UriParser.NewsUri;
+//                         return true;
+//                     }
+//                     break;
+//
+//                 case _NNTP_Mask0:
+//                     if (nChars == 4) {
+//                         syntax = UriParser.NntpUri;
+//                         return true;
+//                     }
+//                     break;
+//
+//                 case _UUID_Mask0:
+//                     if (nChars == 4) {
+//                         syntax = UriParser.UuidUri;
+//                         return true;
+//                     }
+//                     break;
+//
+//                 case _GOPHER_Mask0:
+//                     if (nChars == 6 && (*(int*)(lptr+1)|_INT_LOWERCASE_Mask) == _GOPHER_Mask1) {
+//                         syntax = UriParser.GopherUri;
+//                         return true;
+//                     }
+//                     break;
+//                 case _MAILTO_Mask0:
+//                     if (nChars == 6 && (*(int*)(lptr+1)|_INT_LOWERCASE_Mask) == _MAILTO_Mask1) {
+//                         syntax = UriParser.MailToUri;
+//                         return true;
+//                     }
+//                     break;
+//
+//                 case _TELNET_Mask0:
+//                     if (nChars == 6 && (*(int*)(lptr+1)|_INT_LOWERCASE_Mask) == _TELNET_Mask1) {
+//                         syntax = UriParser.TelnetUri;
+//                         return true;
+//                     }
+//                     break;
+//
+//                 case _NETXXX_Mask0:
+//                     if (nChars == 8 && (*(lptr+1)|_LOWERCASE_Mask) == _NETPIPE_Mask1) {
+//                         syntax = UriParser.NetPipeUri;
+//                         return true;
+//                     }
+//                     else if (nChars == 7 && (*(lptr+1)|_LOWERCASE_Mask) == _NETTCP_Mask1) {
+//                         syntax = UriParser.NetTcpUri;
+//                         return true;
+//                     }
+//                     break;
+//
+//                 case _LDAP_Mask0:
+//                     if (nChars == 4) {
+//                         syntax = UriParser.LdapUri;
+//                         return true;
+//                     }
+//                     break;
+//                 default:    break;
+//             }
+//             return false;
+//         }
+//
+//         //
+//         //
+//         // This will check whether a scheme string follows the rules
+//         //
+//         unsafe static private ParsingError CheckSchemeSyntax(char* ptr, ushort length, ref UriParser syntax) {
+//             //First character must be an alpha
+//         {
+//             char c = *ptr;
+//             if (c >= 'a' && c <= 'z') {
+//                 ;
+//             } else if (c >= 'A' && c <= 'Z') {
+//                 *ptr = (char)(c | 0x20);    //make it lowercase
+//             } else {
+//                 return ParsingError.BadScheme;
+//             }
+//         }
+//
+//             for (ushort i = 1; i < length; ++i) {
+//                 char c = ptr[i];
+//                 if (c >= 'a' && c <= 'z') {
+//                     ;
+//                 } else if (c >= 'A' && c <= 'Z') {
+//                     ptr[i] = (char)(c | 0x20);    //make it lowercase
+//                 } else if (c >= '0' && c <= '9') {
+//                     ;
+//                 } else if (c == '+' || c == '-' || c == '.') {
+//                     ;
+//                 } else {
+//                     return ParsingError.BadScheme;
+//                 }
+//             }
+//             // A not well-known scheme, needs string creation
+//             // Note it is already in the lower case as required.
+//             string str  =  new string(ptr, 0, length);
+//             syntax = UriParser.FindOrFetchAsUnknownV1Syntax(str);
+//             return ParsingError.None;
+//         }
+//         //
+//         //
+//         // Checks the syntax of an authority component. It may also get a userInfo if present
+//         // Returns an error if no/mailformed authority found
+//         // Does not NOT touch m_Info
+//         // Returns position of the Path component
+//         //
+//         // Must be called in the ctor only
+//         private unsafe ushort CheckAuthorityHelper( char* pString, ushort idx, ushort length,
+//             ref ParsingError err, ref Flags flags, UriParser syntax, ref string newHost )
+//         {
+//             int end = length;
+//             char ch;
+//             int startInput = idx;
+//             ushort start = idx;
+//             newHost = null;
+//             bool justNormalized = false;
+//             bool iriParsing = (s_IriParsing && IriParsingStatic(syntax)); // perf
+//             bool hasUnicode = ((flags & Flags.HasUnicode) != 0); // perf
+//             bool hostNotUnicodeNormalized = ((flags & Flags.HostUnicodeNormalized) == 0); // perf
+//             UriSyntaxFlags syntaxFlags = syntax.Flags;
+//
+//             // need to build new Iri'zed string
+//             if (hasUnicode && iriParsing && hostNotUnicodeNormalized){
+//                 newHost = m_originalUnicodeString.Substring(0, startInput);
+//             }
+//
+//             //Special case is an empty authority
+//             if (idx == length || ((ch=pString[idx]) == '/' || (ch == '\\' && StaticIsFile(syntax)) || ch == '#' || ch == '?'))
+//             {
+//                 if (syntax.InFact(UriSyntaxFlags.AllowEmptyHost))
+//                 {
+//                     flags &= ~Flags.UncPath;    //UNC cannot have an empty hostname
+//                     if (StaticInFact(flags, Flags.ImplicitFile))
+//                         err = ParsingError.BadHostName;
+//                     else
+//                         flags |= Flags.BasicHostType;
+//                 }
+//                 else
+//                     err = ParsingError.BadHostName;
+//
+//                 if (hasUnicode && iriParsing && hostNotUnicodeNormalized){
+//                     flags |= Flags.HostUnicodeNormalized;// no host
+//                 }
+//
+//                  return idx;
+//             }
+//
+// //#if PLATFORM_UNIX
+// //            if (StaticIsFile(syntax) && ch != '/') {
+// //                // On UNIX a file URL may only have an empty authority
+// //                err = ParsingError.NonEmptyHost;
+// //                return idx;
+// //            }
+// //#endif // PLATFORM_UNIX
+//
+//             string userInfoString = null;
+//             // Attempt to parse user info first
+//
+//             if ((syntaxFlags & UriSyntaxFlags.MayHaveUserInfo) != 0)
+//             {
+//                 for (; start < end; ++start)
+//                 {
+//                     if (start == end - 1 || pString[start] == '?' || pString[start] == '#' || pString[start] == '\\' || 
+//                         pString[start] == '/')
+//                     {
+//                         start = idx;
+//                         break;
+//                     }
+//                     else if (pString[start] == '@')
+//                     {
+//                         flags |= Flags.HasUserInfo;
+//
+//                         // Iri'ze userinfo
+//                         if (iriParsing || (s_IdnScope != UriIdnScope.None)){
+//                             if (iriParsing && hasUnicode && hostNotUnicodeNormalized){
+//                                 // Normalize user info
+//                                 userInfoString = IriHelper.EscapeUnescapeIri(pString, startInput, start + 1, UriComponents.UserInfo);
+//                                 try{
+//                                     if (UriParser.ShouldUseLegacyV2Quirks)
+//                                         userInfoString = userInfoString.Normalize(NormalizationForm.FormC);
+//                                 }
+//                                 catch (ArgumentException){
+//                                     err = ParsingError.BadFormat;
+//                                     return idx;
+//                                 }
+//
+//                                 newHost += userInfoString;
+//
+//                                 if (!ServicePointManager.AllowAllUriEncodingExpansion && newHost.Length > ushort.MaxValue){
+//                                     err = ParsingError.SizeLimit;
+//                                     return idx;
+//                                 }
+//                             }
+//                             else{
+//                                 userInfoString = new string(pString, startInput, start - startInput + 1);
+//                             }
+//                         }
+//                         ++start;
+//                         ch = pString[start];
+//                         break;
+//                     }
+//                 }
+//             }
+//
+//             // DNS name only optimization
+//             // Fo an overriden parsing the optimization is suppressed since hostname can be changed to anything
+//             bool dnsNotCanonical = ((syntaxFlags & UriSyntaxFlags.SimpleUserSyntax) == 0);
+//
+//             if (ch == '[' && syntax.InFact(UriSyntaxFlags.AllowIPv6Host) 
+//                 && IPv6AddressHelper.IsValid(pString, (int)start+1, ref end))
+//             {
+//                 flags |= Flags.IPv6HostType;
+//
+//                 // Force load config here if config not loaded earlier since we handle IsWellFormed differently
+//                 // for IPv6 if the iri parsing flag is on or off
+//                 if (!s_ConfigInitialized) {
+//                     InitializeUriConfig();
+//                     m_iriParsing = (s_IriParsing && IriParsingStatic(syntax));
+//                 }
+//
+//                 if (hasUnicode && iriParsing && hostNotUnicodeNormalized) {
+//                     newHost += new string(pString, start, end - start);
+//                     flags |= Flags.HostUnicodeNormalized;
+//                     justNormalized = true;
+//                 }
+//             }
+//             else if ( ch <= '9' && ch >= '0' && syntax.InFact(UriSyntaxFlags.AllowIPv4Host) &&
+//                 IPv4AddressHelper.IsValid(pString, (int) start, ref end, false, StaticNotAny(flags, Flags.ImplicitFile), syntax.InFact(UriSyntaxFlags.V1_UnknownUri)))
+//             {
+//                 flags |= Flags.IPv4HostType;
+//
+//                 if (hasUnicode && iriParsing && hostNotUnicodeNormalized){
+//                     newHost += new string(pString, start, end - start);
+//                     flags |= Flags.HostUnicodeNormalized;
+//                     justNormalized = true;
+//                 }
+//             }
+//             else if (((syntaxFlags & UriSyntaxFlags.AllowDnsHost)!= 0) && !iriParsing &&
+//            DomainNameHelper.IsValid(pString, start, ref end, ref dnsNotCanonical, StaticNotAny(flags, Flags.ImplicitFile)))
+//             {
+//                 // comes here if there are only ascii chars in host with original parsing and no Iri
+//
+//                 flags |= Flags.DnsHostType;
+//                 if (!dnsNotCanonical) {
+//                     flags |= Flags.CanonicalDnsHost;
+//                 }
+//
+//                 if ((s_IdnScope != UriIdnScope.None)){
+//                     // check if intranet
+//                     //
+//                     if ((s_IdnScope == UriIdnScope.AllExceptIntranet) && IsIntranet(new string(pString, 0, end))){
+//                         flags |= Flags.IntranetUri;
+//                     }
+//                     if (AllowIdnStatic(syntax, flags)){
+//                         bool allAscii = true;
+//                         bool atLeastOneIdn = false;
+//
+//                         string idnValue = DomainNameHelper.UnicodeEquivalent(pString, start, end, ref allAscii, ref atLeastOneIdn);
+//
+//                         // did we find at least one valid idn
+//                         if (atLeastOneIdn)
+//                         {
+//                             // need to switch string here since we didnt know before hand there there was an idn host
+//                             if (StaticNotAny(flags, Flags.HasUnicode))
+//                                 m_originalUnicodeString = m_String; // lazily switching strings
+//                             flags |= Flags.IdnHost;
+//
+//                             // need to build string for this special scenario
+//                             newHost = m_originalUnicodeString.Substring(0, startInput) + userInfoString + idnValue;
+//                             flags |= Flags.CanonicalDnsHost;
+//                             m_DnsSafeHost = new string(pString, start, end - start);
+//                             justNormalized = true;
+//                         }
+//                         flags |= Flags.HostUnicodeNormalized;
+//                     }
+//                 }
+//             }
+//             else if (((syntaxFlags & UriSyntaxFlags.AllowDnsHost) != 0)
+//                     && ((syntax.InFact(UriSyntaxFlags.AllowIriParsing) && hostNotUnicodeNormalized)
+//                             || syntax.InFact(UriSyntaxFlags.AllowIdn))
+//                     && DomainNameHelper.IsValidByIri(pString, start, ref end, ref dnsNotCanonical,
+//                                             StaticNotAny(flags, Flags.ImplicitFile)))
+//             {
+//                 CheckAuthorityHelperHandleDnsIri(pString, start, end, startInput, iriParsing, hasUnicode, syntax, 
+//                     userInfoString, ref flags, ref justNormalized, ref newHost, ref err);
+//             }
+// #if !PLATFORM_UNIX
+//             else if ((syntaxFlags & UriSyntaxFlags.AllowUncHost) != 0)
+//             {
+//                 //
+//                 // This must remain as the last check befor BasicHost type
+//                 //
+//                 if (UncNameHelper.IsValid(pString, start, ref end, StaticNotAny(flags, Flags.ImplicitFile)))
+//                 {
+//                     if (end - start <= UncNameHelper.MaximumInternetNameLength)
+//                     {
+//                         flags |= Flags.UncHostType;
+//                         if (hasUnicode && iriParsing && hostNotUnicodeNormalized)
+//                         {
+//                             newHost += new string(pString, start, end - start);
+//                             flags |= Flags.HostUnicodeNormalized;
+//                             justNormalized = true;
+//                         }
+//                     }
+//                 }
+//             }
+// #endif // !PLATFORM_UNIX
+//
+//             // The deal here is that we won't allow '\' host terminator except for the File scheme
+//             // If we see '\' we try to make it a part of of a Basic host
+//             if (end < length && pString[end] == '\\' && (flags & Flags.HostTypeMask) != Flags.HostNotParsed 
+//                 && !StaticIsFile(syntax))
+//             {
+//                 if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri))
+//                 {
+//                     err = ParsingError.BadHostName;
+//                     flags |= Flags.UnknownHostType;
+//                     return (ushort) end;
+//                 }
+//                 flags &= ~Flags.HostTypeMask;
+//             }
+//             // Here we have checked the syntax up to the end of host
+//             // The only thing that can cause an exception is the port value
+//             // Spend some (duplicated) cycles on that.
+//             else if (end < length && pString[end] == ':')
+//             {
+//                 if (syntax.InFact(UriSyntaxFlags.MayHavePort))
+//                 {
+//                     int port = 0;
+//                     int startPort = end;
+//                     for (idx = (ushort)(end+1); idx < length; ++idx) {
+//                         ushort val = (ushort)((ushort)pString[idx] - (ushort)'0');
+//                         if ((val >= 0) && (val <= 9))
+//                         {
+//                             if ((port = (port * 10 + val)) > 0xFFFF)
+//                                 break;
+//                         }
+//                         else if (val == unchecked((ushort)('/' - '0')) || val == (ushort)('?' - '0') 
+//                             || val == unchecked((ushort)('#' - '0')))
+//                         {
+//                             break;
+//                         }
+//                         else
+//                         {
+//                             // The second check is to keep compatibility with V1 until the UriParser is registered
+//                             if(syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost) 
+//                                 && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri))
+//                             {
+//                                 flags &= ~Flags.HostTypeMask;
+//                                 break;
+//                             }
+//                             else
+//                             {
+//                                 err = ParsingError.BadPort;
+//                                 return idx;
+//                             }
+//                         }
+//                     }
+//                     // check on 0-ffff range
+//                     if (port > 0xFFFF)
+//                     {
+//                         if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost))
+//                         {
+//                             flags &= ~Flags.HostTypeMask;
+//                         }
+//                         else
+//                         {
+//                             err = ParsingError.BadPort;
+//                             return idx;
+//                         }
+//                     }
+//
+//                     if (iriParsing && hasUnicode && justNormalized){
+//                         newHost += new string(pString, startPort, idx - startPort);
+//                     }
+//                 }
+//                 else
+//                 {
+//                     flags &= ~Flags.HostTypeMask;
+//                 }
+//
+//             }
+//
+//             // check on whether nothing has worked out
+//             if ((flags & Flags.HostTypeMask) == Flags.HostNotParsed)
+//             {
+//                 //No user info for a Basic hostname
+//                 flags &= ~Flags.HasUserInfo;
+//                 // Some schemes do not allow HostType = Basic (plus V1 almost never understands this cause of a bug)
+//                 //
+//                 if(syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost))
+//                 {
+//                     flags |= Flags.BasicHostType;
+//                     for (end = idx; end < length; ++end) {
+//                         if (pString[end] == '/' || (pString[end] == '?' || pString[end] == '#')) {
+//                             break;
+//                         }
+//                     }
+//                     CheckAuthorityHelperHandleAnyHostIri(pString, startInput, end, iriParsing, hasUnicode, syntax,
+//                                                             ref flags, ref newHost, ref err);
+//                 }
+//                 else
+//                 {
+//                     //
+//                     // ATTN V1 compat: V1 supports hostnames like ".." and ".", and so we do but only for unknown schemes.
+//                     //                 (VsWhidbey#438821)
+//                     if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri))
+//                     {
+//                         // Can assert here that the host is not empty so we will set dotFound
+//                         // at least once or fail before exiting the loop
+//                         bool dotFound = false;
+//                         int startOtherHost = idx;
+//                         for (end = idx; end < length; ++end)
+//                         {
+//                             if (dotFound && (pString[end] == '/' || pString[end] == '?' || pString[end] == '#'))
+//                                 break;
+//                             else if (end < (idx + 2) && pString[end] == '.')
+//                             {
+//                                 // allow one or two dots
+//                                 dotFound = true;
+//                             }
+//                             else
+//                             {
+//                                 //failure
+//                                 err = ParsingError.BadHostName;
+//                                 flags |= Flags.UnknownHostType;
+//                                 return idx;
+//                             }
+//                         }
+//                         //success
+//                         flags |= Flags.BasicHostType;
+//
+//                         if (iriParsing && hasUnicode
+//                             && StaticNotAny(flags, Flags.HostUnicodeNormalized)){
+//                             // Normalize any other host
+//                             String user = new string(pString, startOtherHost, end - startOtherHost);
+//                             try
+//                             {
+//                                 newHost += user.Normalize(NormalizationForm.FormC);
+//                             }
+//                             catch (ArgumentException){
+//                                 err = ParsingError.BadFormat;
+//                                 return idx;
+//                             }
+//
+//                             flags |= Flags.HostUnicodeNormalized;
+//                         }
+//                     }
+//                     else if (syntax.InFact(UriSyntaxFlags.MustHaveAuthority) ||
+//                              (syntax.InFact(UriSyntaxFlags.MailToLikeUri) && !UriParser.ShouldUseLegacyV2Quirks))
+//                     {
+//                         err = ParsingError.BadHostName;
+//                         flags |= Flags.UnknownHostType;
+//                         return idx;
+//                     }
+//                 }
+//             }
+//             return (ushort) end;
+//         }
+//
+//         unsafe void CheckAuthorityHelperHandleDnsIri( char* pString, ushort start, int end, int startInput,
+//             bool iriParsing, bool hasUnicode, UriParser syntax, string userInfoString, ref Flags flags, 
+//             ref bool justNormalized, ref string newHost, ref ParsingError err)
+//         {
+//             // comes here only if host has unicode chars and iri is on or idn is allowed
+//
+//             flags |= Flags.DnsHostType;
+//
+//             // check if intranet
+//             //
+//             if ((s_IdnScope == UriIdnScope.AllExceptIntranet) && IsIntranet(new string(pString, 0, end)))
+//             {
+//                 flags |= Flags.IntranetUri;
+//             }
+//
+//             if (AllowIdnStatic(syntax, flags))
+//             {
+//                 bool allAscii = true;
+//                 bool atLeastOneIdn = false;
+//
+//                 string idnValue = DomainNameHelper.IdnEquivalent(pString, start, end, ref allAscii, ref atLeastOneIdn);
+//                 string UniEquvlt = DomainNameHelper.UnicodeEquivalent(idnValue, pString, start, end);
+//
+//                 if (!allAscii)
+//                     flags |= Flags.UnicodeHost; // we have a unicode host
+//
+//                 if (atLeastOneIdn)
+//                     flags |= Flags.IdnHost;   // we have at least one valid idn label
+//
+//                 if (allAscii && atLeastOneIdn && StaticNotAny(flags, Flags.HasUnicode))
+//                 {
+//                     // original string location changed lazily
+//                     m_originalUnicodeString = m_String;
+//                     newHost = m_originalUnicodeString.Substring(0, startInput) +
+//                         (StaticInFact(flags, Flags.HasUserInfo) ? userInfoString : null);
+//                     justNormalized = true;
+//                 }
+//                 else if (!iriParsing && (StaticInFact(flags, Flags.UnicodeHost) || StaticInFact(flags, Flags.IdnHost)))
+//                 {
+//                     // original string location changed lazily
+//                     m_originalUnicodeString = m_String;
+//                     newHost = m_originalUnicodeString.Substring(0, startInput) +
+//                         (StaticInFact(flags, Flags.HasUserInfo) ? userInfoString : null);
+//                     justNormalized = true;
+//                 }
+//
+//                 if (!(allAscii && !atLeastOneIdn))
+//                 {
+//                     m_DnsSafeHost = idnValue;
+//                     newHost += UniEquvlt;
+//                     justNormalized = true;
+//                 }
+//                 else if (allAscii && !atLeastOneIdn && iriParsing && hasUnicode)
+//                 {
+//                     newHost += UniEquvlt;
+//                     justNormalized = true;
+//                 }
+//             }
+//             else
+//             {
+//                 if (hasUnicode)
+//                 {
+//                     string temp = StripBidiControlCharacter(pString, start, end - start);
+//                     try{
+//                         newHost += ((temp != null) ? temp.Normalize(NormalizationForm.FormC) : null);
+//                     }
+//                     catch (ArgumentException){
+//                         err = ParsingError.BadHostName;
+//                     }
+//                     justNormalized = true;
+//                 }
+//             }
+//             flags |= Flags.HostUnicodeNormalized;
+//         }
+//
+//         unsafe void CheckAuthorityHelperHandleAnyHostIri(char* pString, int startInput, int end,
+//                                             bool iriParsing, bool hasUnicode, UriParser syntax,
+//                                             ref Flags flags, ref string newHost, ref ParsingError err)
+//         {
+//             if (StaticNotAny(flags, Flags.HostUnicodeNormalized) && (AllowIdnStatic(syntax, flags) || 
+//                 (iriParsing && hasUnicode)))
+//             {
+//                 // Normalize any other host or do idn
+//                 String user = new string(pString, startInput, end - startInput);
+//
+//                 if (AllowIdnStatic(syntax, flags))
+//                 {
+//                     bool allAscii = true;
+//                     bool atLeastOneIdn = false;
+//
+//                     string UniEquvlt = DomainNameHelper.UnicodeEquivalent(pString, startInput, end, ref allAscii, 
+//                         ref atLeastOneIdn);
+//
+//                     if (((allAscii && atLeastOneIdn) || !allAscii) && !(iriParsing && hasUnicode))
+//                     {
+//                         // original string location changed lazily
+//                         m_originalUnicodeString = m_String;
+//                         newHost = m_originalUnicodeString.Substring(0, startInput);
+//                         flags |= Flags.HasUnicode;
+//                     }
+//                     if (atLeastOneIdn || !allAscii)
+//                     {
+//                         newHost += UniEquvlt;
+//                         string bidiStrippedHost = null;
+//                         m_DnsSafeHost = DomainNameHelper.IdnEquivalent(pString, startInput, end, ref  allAscii, 
+//                             ref bidiStrippedHost);
+//                         if (atLeastOneIdn)
+//                             flags |= Flags.IdnHost;
+//                         if (!allAscii)
+//                             flags |= Flags.UnicodeHost;
+//                     }
+//                     else if (iriParsing && hasUnicode)
+//                     {
+//                         newHost += user;
+//
+//                     }
+//                 }
+//                 else
+//                 {
+//                     try{
+//                         newHost += user.Normalize(NormalizationForm.FormC);
+//                     }
+//                     catch (ArgumentException){
+//                         err = ParsingError.BadHostName;
+//                     }
+//                 }
+//
+//                 flags |= Flags.HostUnicodeNormalized;
+//             }
+//         }
+//
+//         //
+//         //
+//         // The method checks whether a string needs transformation before going to display or wire
+//         //
+//         // Parameters:
+//         // - escaped   true = treat all valid escape sequences as escaped sequences, false = escape all %
+//         // - delim     a character signalling the termination of the component being checked
+//         //
+//         // When delim=='?', then '#' character is also considered as delimiter additionally to passed '?'.
+//         //
+//         // The method pays attention to the dots and slashes so to signal potential Path compression action needed.
+//         // Even that is not required for other components, the cycles are still spent (little inefficiency)
+//         //
+//
+//         internal const char c_DummyChar = (char) 0xFFFF;     //An Invalid Unicode character used as a dummy char passed into the parameter
+//         internal const char c_EOL       = (char) 0xFFFE;     //An Invalid Unicode character used by CheckCanonical as "no delimiter condition"
+//         [Flags]
+//         private enum Check {
+//             None            = 0x0,
+//             EscapedCanonical= 0x1,
+//             DisplayCanonical= 0x2,
+//             DotSlashAttn    = 0x4,
+//             DotSlashEscaped = 0x80,
+//             BackslashInPath = 0x10,
+//             ReservedFound   = 0x20,
+//             NotIriCanonical = 0x40,
+//             FoundNonAscii =    0x8
+//         }
+//
+//         //
+//         // Finds the end of component
+//         //
+//
+//         private unsafe void FindEndOfComponent(string input, ref ushort idx, ushort end, char delim)
+//         {
+//             fixed (char* str = input)
+//             {
+//                 FindEndOfComponent(str, ref idx, end, delim);
+//             }
+//         }
+//         private unsafe void FindEndOfComponent(char* str, ref ushort idx, ushort end, char delim)
+//         {
+//             char c = c_DummyChar;
+//             ushort i=idx;
+//             for (; i < end; ++i)
+//             {
+//                 c = str[i];
+//                 if (c == delim)
+//                 {
+//                     break;
+//                 }
+//                 else if (delim == '?' && c == '#' && (m_Syntax != null && m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
+//                 {
+//                     // this is a special case when deciding on Query/Fragment
+//                     break;
+//                 }
+//             }
+//             idx = i;
+//         }
+//
+//         //
+//         // Used by ParseRemaining as well by InternalIsWellFormedOriginalString
+//         //
+//         private unsafe Check CheckCanonical(char* str, ref ushort idx, ushort end, char delim) {
+//             Check res = Check.None;
+//             bool needsEscaping = false;
+//             bool foundEscaping = false;
+//
+//             char c = c_DummyChar;
+//             ushort i=idx;
+//             for (; i < end; ++i)
+//             {
+//                 c = str[i];
+//                 // Control chars usually should be escaped in any case
+//                 if (c <= '\x1F' || (c >= '\x7F' && c <= '\x9F'))
+//                 {
+//                     needsEscaping = true;
+//                     foundEscaping = true;
+//                     res |= Check.ReservedFound;
+//                 }
+//                 else if (c > 'z' && c != '~') {
+//                     if(m_iriParsing){
+//                         bool valid = false;
+//                         res |= Check.FoundNonAscii;
+//
+//                         if (Char.IsHighSurrogate(c)){
+//                             if ((i + 1) < end){
+//                                 bool surrPair = false;
+//                                 valid = IriHelper.CheckIriUnicodeRange(c, str[i + 1], ref surrPair, true);
+//                             }
+//                         }
+//                         else{
+//                             valid = IriHelper.CheckIriUnicodeRange(c, true);
+//                         }
+//                         if (!valid) res |= Check.NotIriCanonical;
+//                     }
+//
+//                     if (!needsEscaping) needsEscaping = true;
+//                 }
+//                 else if (c == delim) {
+//                     break;
+//                 }
+//                 else if (delim == '?' && c == '#' && (m_Syntax != null && m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment))) {
+//                     // this is a special case when deciding on Query/Fragment
+//                     break;
+//                 }
+//                 else if (c == '?') {
+//                     if (IsImplicitFile || (m_Syntax != null && !m_Syntax.InFact(UriSyntaxFlags.MayHaveQuery) 
+//                         && delim != c_EOL))
+//                     {
+//                         // VsWhidbey#87423
+//                         // If found as reserved this char is not suitable for safe unescaped display
+//                         // Will need to escape it when both escaping and unescaping the string
+//                         res |= Check.ReservedFound;
+//                         foundEscaping = true;
+//                         needsEscaping = true;
+//                     }
+//                 }
+//                 else if (c == '#') {
+//                     needsEscaping = true;
+//                     if (IsImplicitFile || (m_Syntax != null && !m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment))) {
+//                         // VsWhidbey#87423, 122037
+//                         // If found as reserved this char is not suitable for safe unescaped display
+//                         // Will need to escape it when both escaping and unescaping the string
+//                         res |= Check.ReservedFound;
+//                         foundEscaping = true;
+//                     }
+//                 }
+//                 else if (c == '/' || c == '\\') {
+//                     if ((res & Check.BackslashInPath) == 0 && c == '\\') {
+//                         res |= Check.BackslashInPath;
+//                     }
+//                     if ((res & Check.DotSlashAttn) == 0 && i+1 != end && (str[i+1] == '/' || str[i+1] == '\\' )) {
+//                         res |= Check.DotSlashAttn;
+//                     }
+//                 }
+//                 else if (c == '.') {
+//                     if ((res & Check.DotSlashAttn) == 0 && i+1 == end || str[i+1] == '.' || str[i+1] == '/' 
+//                         || str[i+1] == '\\' || str[i+1] == '?' || str[i+1] == '#') {
+//                         res |= Check.DotSlashAttn;
+//                     }
+//                 }
+//                 else if (!needsEscaping && ((c <= '"' && c != '!') || (c >= '[' && c <= '^') || c == '>' 
+//                     || c == '<' || c == '`')) {
+//                     needsEscaping = true;
+//                 }
+//                 else if (c == '%') {
+//                     if (!foundEscaping) foundEscaping = true;
+//                     //try unescape a byte hex escaping
+//                     if (i + 2 < end && (c = UriHelper.EscapedAscii(str[i + 1], str[i + 2])) != c_DummyChar)
+//                     {
+//                         if (c == '.' || c == '/' || c == '\\') {
+//                             res |= Check.DotSlashEscaped;
+//                         }
+//                         i+=2;
+//                         continue;
+//                     }
+//                     // otherwise we follow to non escaped case
+//                     if (!needsEscaping) {
+//                         needsEscaping = true;
+//                     }
+//                 }
+//             }
+//
+//             if (foundEscaping) {
+//                 if (!needsEscaping) {
+//                     res |= Check.EscapedCanonical;
+//                 }
+//             }
+//             else {
+//                 res |= Check.DisplayCanonical;
+//                 if (!needsEscaping) {
+//                     res |= Check.EscapedCanonical;
+//                 }
+//             }
+//             idx = i;
+//             return res;
+//         }
+//
+//         //
+//         // Returns the escaped and canonicalized path string
+//         // the passed array must be long enough to hold at least
+//         // canonical unescaped path representation (allocated by the caller)
+//         //
+//         private unsafe char[] GetCanonicalPath(char[] dest, ref int pos, UriFormat formatAs)
+//         {
+//
+//             if (InFact(Flags.FirstSlashAbsent))
+//                 dest[pos++] = '/';
+//
+//             if (m_Info.Offset.Path == m_Info.Offset.Query)
+//                 return dest;
+//
+//             int end = pos;
+//
+//             int dosPathIdx = SecuredPathIndex;
+//
+//             // Note that unescaping and then escapig back is not transitive hence not safe.
+//             // We are vulnerable due to the way the UserEscaped flag is processed (see NDPWhidbey#10612 bug).
+//             // Try to unescape only needed chars.
+//             if (formatAs == UriFormat.UriEscaped)
+//             {
+//                 if (InFact(Flags.ShouldBeCompressed))
+//                 {
+//                     m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path);
+//                     end += (m_Info.Offset.Query - m_Info.Offset.Path);
+//
+//                     // If the path was found as needed compression and contains escaped characters, unescape only 
+//                     // interesting characters (safe)
+//
+//                     if (m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes) && InFact(Flags.PathNotCanonical) 
+//                         && !IsImplicitFile)
+//                     {
+//                         fixed (char* pdest = dest)
+//                         {
+//                             UnescapeOnly(pdest, pos, ref end, '.', '/', 
+//                                 m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) ? '\\' : c_DummyChar);
+//                         }
+//                     }
+//                 }
+//                 else
+//                 {
+//                     //
+//                     if (InFact(Flags.E_PathNotCanonical) && NotAny(Flags.UserEscaped)) {
+//                         string str = m_String;
+//
+//                         // Check on not canonical disk designation like C|\, should be rare, rare case
+//                         if (dosPathIdx != 0 && str[dosPathIdx + m_Info.Offset.Path -1] == '|')
+//                         {
+//                             str = str.Remove(dosPathIdx + m_Info.Offset.Path -1, 1);
+//                             str = str.Insert(dosPathIdx + m_Info.Offset.Path -1, ":");
+//                         }
+//                         dest = UriHelper.EscapeString(str, m_Info.Offset.Path, m_Info.Offset.Query, dest, ref end, true, 
+//                             '?', '#', IsImplicitFile? c_DummyChar: '%');
+//                     }
+//                     else {
+//                         m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path);
+//                         end += (m_Info.Offset.Query - m_Info.Offset.Path);
+//                     }
+//                 }
+//             }
+//             else
+//             {
+//                 m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path);
+//                 end += (m_Info.Offset.Query - m_Info.Offset.Path);
+//
+//                 if (InFact(Flags.ShouldBeCompressed))
+//                 {
+//                     // If the path was found as needed compression and contains escaped characters, 
+//                     // unescape only interesting characters (safe)
+//
+//                     if (m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes) && InFact(Flags.PathNotCanonical) 
+//                         && !IsImplicitFile)
+//                     {
+//                         fixed (char* pdest = dest)
+//                         {
+//                             UnescapeOnly(pdest, pos, ref end, '.', '/', 
+//                                 m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) ? '\\' : c_DummyChar);
+//                         }
+//                     }
+//                 }
+//             }
+//
+//             // Here we already got output data as copied into dest array
+//             // We just may need more processing of that data
+//
+//             //
+//             // if this URI is using 'non-proprietary' disk drive designation, convert to MS-style
+//             //
+//             // (path is already  >= 3 chars if recognized as a DOS-like)
+//             //
+//             if (dosPathIdx != 0 && dest[dosPathIdx + pos - 1] == '|')
+//                 dest[dosPathIdx + pos - 1] = ':';
+//
+//             if (InFact(Flags.ShouldBeCompressed))
+//             {
+//                 // It will also convert back slashes if needed
+//                 dest = Compress(dest, (ushort)(pos + dosPathIdx), ref end, m_Syntax);
+//                 if (dest[pos] == '\\')
+//                     dest[pos] = '/';
+//
+//                 // Escape path if requested and found as not fully escaped
+//                 if (formatAs == UriFormat.UriEscaped && NotAny(Flags.UserEscaped) && InFact(Flags.E_PathNotCanonical)) {
+//                     //
+//                     string srcString = new string(dest, pos, end-pos);
+//                     dest = UriHelper.EscapeString(srcString, 0, end - pos, dest, ref pos, true, '?', '#', 
+//                         IsImplicitFile ? c_DummyChar : '%');
+//                     end = pos;
+//                 }
+//             }
+//             else if (m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) && InFact(Flags.BackslashInPath))
+//             {
+//                 for (int i = pos; i < end; ++i)
+//                     if (dest[i] == '\\') dest[i] = '/';
+//             }
+//
+//             if (formatAs != UriFormat.UriEscaped && InFact(Flags.PathNotCanonical))
+//             {
+//                 UnescapeMode mode;
+//                 if (InFact(Flags.PathNotCanonical))
+//                 {
+//                     switch (formatAs)
+//                     {
+//                     case V1ToStringUnescape:
+//
+//                         mode = (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) 
+//                             | UnescapeMode.V1ToStringFlag;
+//                         if (IsImplicitFile)
+//                             mode &= ~UnescapeMode.Unescape;
+//                         break;
+//
+//                     case UriFormat.Unescaped:
+//                         mode = IsImplicitFile ? UnescapeMode.CopyOnly 
+//                             : UnescapeMode.Unescape | UnescapeMode.UnescapeAll;
+//                         break;
+//
+//                     default: // UriFormat.SafeUnescaped
+//
+//                         mode = InFact(Flags.UserEscaped)? UnescapeMode.Unescape: UnescapeMode.EscapeUnescape;
+//                         if (IsImplicitFile)
+//                             mode &= ~UnescapeMode.Unescape;
+//                         break;
+//                     }
+//                 }
+//                 else {
+//                     mode = UnescapeMode.CopyOnly;
+//                 }
+//
+//                 char[] dest1 = new char[dest.Length];
+//                 Buffer.BlockCopy(dest, 0, dest1, 0, end<<1);
+//                 fixed (char *pdest = dest1)
+//                 {
+//                     dest = UriHelper.UnescapeString(pdest, pos, end, dest, ref pos, '?', '#', c_DummyChar, mode, 
+//                         m_Syntax, false);
+//                 }
+//             }
+//             else
+//             {
+//                 pos = end;
+//             }
+//
+//             return dest;
+//         }
+//
+//         // works only with ASCII characters, used to partially unescape path before compressing
+//         private unsafe static void UnescapeOnly(char* pch, int start, ref int end, char ch1, char ch2, char ch3) {
+//             if (end - start < 3) {
+//                 //no chance that something is escaped
+//                 return;
+//             }
+//
+//             char *pend = pch + end-2;
+//             pch += start;
+//             char *pnew = null;
+//
+//             over:
+//
+//             // Just looking for a interested escaped char
+//             if (pch >= pend)    goto done;
+//             if(*pch++ != '%')   goto over;
+//
+//             char ch = UriHelper.EscapedAscii(*pch++, *pch++);
+//             if (!(ch == ch1 || ch == ch2 || ch == ch3)) goto over;
+//
+//             // Here we found something and now start copying the scanned chars
+//             pnew = pch-2;
+//             *(pnew-1) = ch;
+//
+//             over_new:
+//
+//             if (pch >= pend)                goto done;
+//             if((*pnew++ = *pch++) != '%')   goto over_new;
+//
+//             ch = UriHelper.EscapedAscii((*pnew++ = *pch++), (*pnew++ = *pch++));
+//             if (!(ch == ch1 || ch == ch2 || ch == ch3)) {
+//                 goto over_new;
+//             }
+//
+//             pnew -= 2;
+//             *(pnew-1) = ch;
+//
+//             goto over_new;
+//
+//             done:
+//             pend+=2;
+//
+//             if (pnew == null) {
+//                 //nothing was found
+//                 return;
+//             }
+//
+//             //the tail may be already processed
+//             if(pch == pend) {
+//                 end -= (int) (pch-pnew);
+//                 return;
+//             }
+//
+//             *pnew++ = *pch++;
+//             if(pch == pend) {
+//                 end -= (int) (pch-pnew);
+//                 return;
+//             }
+//             *pnew++ = *pch++;
+//             end -= (int) (pch-pnew);
+//         }
+//
+//         //
+//         //
+//         // This will compress any "\" "/../" "/./" "///" "/..../" /XXX.../, etc found in the input
+//         //
+//         // The passed syntax controls whether to use agressive compression or the one specified in RFC 2396
+//         //
+//         //
+//         private static char[] Compress(char[] dest, ushort start, ref int destLength, UriParser syntax)
+//         {
+//             ushort  slashCount      = 0;
+//             ushort  lastSlash       = 0;
+//             ushort  dotCount        = 0;
+//             ushort  removeSegments  = 0;
+//
+//             unchecked {
+//                 //ushort i == -1 and start == -1 overflow is ok here
+//                 ushort  i = (ushort)((ushort)destLength - (ushort)1);
+//                 start = (ushort)(start-1);
+//
+//                 for (; i != start ; --i) {
+//                     char ch = dest[i];
+//                     if (ch == '\\' && syntax.InFact(UriSyntaxFlags.ConvertPathSlashes)) {
+//                         dest[i] = ch = '/';
+//                     }
+//
+//                     //
+//                     // compress multiple '/' for file URI
+//                     //
+//                     if (ch == '/') {
+//                         ++slashCount;
+//                         /*
+//                         QFE 4390 - remove the compression of multiple slashes to a single slash
+//                         if (slashCount > 1) {
+//                             continue;
+//                         }
+// 			*/
+//                     }
+//                     else {
+//                         if (slashCount > 1) {
+//                             /*
+//                             QFE 4390 - remove the compression of multiple slashes to a single slash
+//                             if (syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath))
+//                             {
+//                                 // We saw > 1 slashes so remove all but the last one
+//                                 // dest.Remove(i+1, slashCount -1);
+//                                 Buffer.BlockCopy(dest, (i + slashCount) << 1, dest, (i + 1) << 1, 
+//                                     (destLength - (i + slashCount)) << 1);
+//                                 destLength -= (slashCount - 1);
+//                             }
+// 			    */
+//                             // else preserve repeated slashes
+//                             lastSlash = (ushort)(i + 1);
+//                         }
+//                         slashCount = 0;
+//                     }
+//
+//                     if (ch == '.') {
+//                         ++dotCount;
+//                         continue;
+//                     }
+//                     else if (dotCount != 0) {
+//
+//                         bool skipSegment = syntax.NotAny(UriSyntaxFlags.CanonicalizeAsFilePath) 
+//                             && (dotCount > 2 || ch != '/' || i == start);
+//
+//                         //
+//                         // Cases:
+//                         // /./                  = remove this segment 
+//                         // /../                 = remove this segment, mark next for removal
+//                         // /....x               = DO NOT TOUCH, leave as is
+//                         // x.../                = DO NOT TOUCH, leave as is, except for V2 legacy mode
+//                         //
+//                         if (!skipSegment && ch == '/') {
+//                             if ((lastSlash == i + dotCount + 1 // "/..../"
+//                                     || (lastSlash == 0 && i + dotCount + 1 == destLength)) // "/..."
+//                                 && (UriParser.ShouldUseLegacyV2Quirks || dotCount <= 2)) {
+//                                 //
+//                                 //  /./ or /.<eos> or /../ or /..<eos>
+//                                 //
+//                                 // just reusing a variable slot we perform //dest.Remove(i+1, dotCount + (lastSlash==0?0:1));
+//                                 lastSlash = (ushort)(i + 1 + dotCount + (lastSlash==0?0:1));
+//                                 Buffer.BlockCopy(dest, lastSlash<<1, dest, (i+1)<<1, (destLength - lastSlash)<<1);
+//                                 destLength -= (lastSlash-i-1);
+//
+//                                 lastSlash = i;
+//                                 if (dotCount == 2) {
+//                                     //
+//                                     // We have 2 dots in between like /../ or /..<eos>,
+//                                     // Mark next segment for removal and remove this /../ or /..
+//                                     //
+//                                     ++removeSegments;
+//                                 }
+//                                 dotCount = 0;
+//                                 continue;
+//                             }
+//                         }
+//                         else if (UriParser.ShouldUseLegacyV2Quirks
+//                             && !skipSegment
+//                             && (removeSegments == 0) 
+//                             && (lastSlash == i+dotCount+1 || (lastSlash == 0 && i+dotCount+1 == destLength))) {
+//                             //
+//                             // Note if removeSegments!=0, then ignore and remove the whole segment later
+//                             //
+//                             // x.../  or  x...<eos>
+//                             // remove trailing dots
+//                             //
+//                             //
+//                             // just reusing a variable slot we perform //dest.Remove(i+1, dotCount);
+//                             dotCount = (ushort)(i + 1 + dotCount);
+//                             Buffer.BlockCopy(dest, dotCount<<1, dest, (i+1)<<1, (destLength - dotCount)<<1);
+//                             destLength -= (dotCount-i-1);
+//                             lastSlash = 0;  //the other dots in this segment will stay intact
+//                             dotCount = 0;
+//                             continue;
+//                         }
+//                             // .NET 4.5 no longer removes trailing dots in a path segment x.../  or  x...<eos>
+//                             dotCount = 0;
+//                         
+//                         //
+//                         // Here all other cases go such as
+//                         // x.[..]y or /.[..]x or (/x.[...][/] && removeSegments !=0)
+//                     }
+//
+//                     //
+//                     // Now we may want to remove a segment because of previous /../
+//                     //
+//                     if (ch == '/') {
+//                         if (removeSegments  != 0) {
+//                             --removeSegments;
+//
+//                             // just reusing a variable slot we perform //dest.Remove(i+1, lastSlash - i);
+//                             lastSlash = (ushort)(lastSlash + 1);
+//                             Buffer.BlockCopy(dest, lastSlash<<1, dest, (i+1)<<1, (destLength - lastSlash)<<1);
+//                             destLength -= (lastSlash-i-1);
+//                         }
+//                     lastSlash = i;
+//                     }
+//                 }
+//
+//                start = (ushort)((ushort)start + (ushort)1);
+//             } //end of unchecked
+//
+//             // Dead Code?
+//             if ((ushort)destLength > start && syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath))
+//             {
+//                 if (slashCount > 1) {
+// 		    /*
+//                     Buffer.BlockCopy(dest, lastSlash << 1, dest, start << 1, (destLength - lastSlash) << 1);
+//                     destLength -= (slashCount - 1);
+//                     */
+//                     //QFE 4390 - Fall through for compat after not multiple slashes to a single slashl
+//                 }
+//                 else if (removeSegments != 0 && dest[start] != '/') {
+//                     //remove first not rooted segment
+//                     // dest.Remove(i+1, lastSlash - i);
+//                     lastSlash = (ushort)(lastSlash + 1);
+//                     Buffer.BlockCopy(dest, lastSlash<<1, dest, start<<1, (destLength - lastSlash)<<1);
+//                     destLength -= lastSlash;
+//                 }
+//                 else if (dotCount != 0) {
+//                     // If final string starts with a segment looking like .[...]/ or .[...]<eos>
+//                     // then we remove this fisrt segment
+//                     if (lastSlash == dotCount+1 || (lastSlash == 0 && dotCount + 1 == destLength)) {
+//                         //dest.Remove(0, dotCount + (lastSlash==0?0:1));
+//                         dotCount = (ushort)(dotCount + (lastSlash==0?0:1));
+//                         Buffer.BlockCopy(dest, dotCount<<1, dest, start<<1, (destLength - dotCount)<<1);
+//                         destLength -= dotCount;
+//                     }
+//                 }
+//             }
+//             return dest;
+//         }
+//
+//         //used by DigestClient
+//         internal static readonly char[] HexLowerChars = {
+//                                    '0', '1', '2', '3', '4', '5', '6', '7',
+//                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+//                                    };
+//
+//         internal static int CalculateCaseInsensitiveHashCode(string text)
+//         {
+//             return StringComparer.InvariantCultureIgnoreCase.GetHashCode(text);
+//         }
+//         //
+//         // CombineUri
+//         //
+//         //  Given 2 URI strings, combine them into a single resultant URI string
+//         //
+//         // Inputs:
+//         //  <argument>  basePart
+//         //      Base URI to combine with
+//         //
+//         //  <argument>  relativePart
+//         //      String expected to be relative URI
+//         //
+//         // Assumes:
+//         //  <basePart> is in canonic form
+//         //
+//         // Returns:
+//         //  Resulting combined URI string
+//         //
+//         private static string CombineUri(Uri basePart, string relativePart, UriFormat uriFormat) {
+//            //NB: relativePart is ensured as not empty by the caller
+//            //    Another assumption is that basePart is an AbsoluteUri
+//
+//            // This method was not optimized for efficiency
+//            // Means a relative Uri ctor may be relatively slow plus it increases the footprint of the baseUri
+//
+//            char c1 = relativePart[0];
+//
+// #if !PLATFORM_UNIX
+//            //check a special case for the base as DOS path and a rooted relative string
+//            if ( basePart.IsDosPath &&
+//                (c1 == '/' || c1 == '\\') &&
+//                (relativePart.Length == 1 || (relativePart[1] != '/' && relativePart[1] != '\\')))
+//            {
+//                // take relative part appended to the base string after the drive letter
+//                int idx = basePart.OriginalString.IndexOf(':');
+//                if (basePart.IsImplicitFile) {
+//                    return basePart.OriginalString.Substring(0, idx+1 ) + relativePart;
+//                }
+//                // The basePart has explicit scheme (could be not file:), take the DOS drive ':' position
+//                idx = basePart.OriginalString.IndexOf(':', idx+1);
+//                return basePart.OriginalString.Substring(0, idx+1 ) + relativePart;
 //            }
-//#endif // PLATFORM_UNIX
-
-            string userInfoString = null;
-            // Attempt to parse user info first
-
-            if ((syntaxFlags & UriSyntaxFlags.MayHaveUserInfo) != 0)
-            {
-                for (; start < end; ++start)
-                {
-                    if (start == end - 1 || pString[start] == '?' || pString[start] == '#' || pString[start] == '\\' || 
-                        pString[start] == '/')
-                    {
-                        start = idx;
-                        break;
-                    }
-                    else if (pString[start] == '@')
-                    {
-                        flags |= Flags.HasUserInfo;
-
-                        // Iri'ze userinfo
-                        if (iriParsing || (s_IdnScope != UriIdnScope.None)){
-                            if (iriParsing && hasUnicode && hostNotUnicodeNormalized){
-                                // Normalize user info
-                                userInfoString = IriHelper.EscapeUnescapeIri(pString, startInput, start + 1, UriComponents.UserInfo);
-                                try{
-                                    if (UriParser.ShouldUseLegacyV2Quirks)
-                                        userInfoString = userInfoString.Normalize(NormalizationForm.FormC);
-                                }
-                                catch (ArgumentException){
-                                    err = ParsingError.BadFormat;
-                                    return idx;
-                                }
-
-                                newHost += userInfoString;
-
-                                if (!ServicePointManager.AllowAllUriEncodingExpansion && newHost.Length > ushort.MaxValue){
-                                    err = ParsingError.SizeLimit;
-                                    return idx;
-                                }
-                            }
-                            else{
-                                userInfoString = new string(pString, startInput, start - startInput + 1);
-                            }
-                        }
-                        ++start;
-                        ch = pString[start];
-                        break;
-                    }
-                }
-            }
-
-            // DNS name only optimization
-            // Fo an overriden parsing the optimization is suppressed since hostname can be changed to anything
-            bool dnsNotCanonical = ((syntaxFlags & UriSyntaxFlags.SimpleUserSyntax) == 0);
-
-            if (ch == '[' && syntax.InFact(UriSyntaxFlags.AllowIPv6Host) 
-                && IPv6AddressHelper.IsValid(pString, (int)start+1, ref end))
-            {
-                flags |= Flags.IPv6HostType;
-
-                // Force load config here if config not loaded earlier since we handle IsWellFormed differently
-                // for IPv6 if the iri parsing flag is on or off
-                if (!s_ConfigInitialized) {
-                    InitializeUriConfig();
-                    m_iriParsing = (s_IriParsing && IriParsingStatic(syntax));
-                }
-
-                if (hasUnicode && iriParsing && hostNotUnicodeNormalized) {
-                    newHost += new string(pString, start, end - start);
-                    flags |= Flags.HostUnicodeNormalized;
-                    justNormalized = true;
-                }
-            }
-            else if ( ch <= '9' && ch >= '0' && syntax.InFact(UriSyntaxFlags.AllowIPv4Host) &&
-                IPv4AddressHelper.IsValid(pString, (int) start, ref end, false, StaticNotAny(flags, Flags.ImplicitFile), syntax.InFact(UriSyntaxFlags.V1_UnknownUri)))
-            {
-                flags |= Flags.IPv4HostType;
-
-                if (hasUnicode && iriParsing && hostNotUnicodeNormalized){
-                    newHost += new string(pString, start, end - start);
-                    flags |= Flags.HostUnicodeNormalized;
-                    justNormalized = true;
-                }
-            }
-            else if (((syntaxFlags & UriSyntaxFlags.AllowDnsHost)!= 0) && !iriParsing &&
-           DomainNameHelper.IsValid(pString, start, ref end, ref dnsNotCanonical, StaticNotAny(flags, Flags.ImplicitFile)))
-            {
-                // comes here if there are only ascii chars in host with original parsing and no Iri
-
-                flags |= Flags.DnsHostType;
-                if (!dnsNotCanonical) {
-                    flags |= Flags.CanonicalDnsHost;
-                }
-
-                if ((s_IdnScope != UriIdnScope.None)){
-                    // check if intranet
-                    //
-                    if ((s_IdnScope == UriIdnScope.AllExceptIntranet) && IsIntranet(new string(pString, 0, end))){
-                        flags |= Flags.IntranetUri;
-                    }
-                    if (AllowIdnStatic(syntax, flags)){
-                        bool allAscii = true;
-                        bool atLeastOneIdn = false;
-
-                        string idnValue = DomainNameHelper.UnicodeEquivalent(pString, start, end, ref allAscii, ref atLeastOneIdn);
-
-                        // did we find at least one valid idn
-                        if (atLeastOneIdn)
-                        {
-                            // need to switch string here since we didnt know before hand there there was an idn host
-                            if (StaticNotAny(flags, Flags.HasUnicode))
-                                m_originalUnicodeString = m_String; // lazily switching strings
-                            flags |= Flags.IdnHost;
-
-                            // need to build string for this special scenario
-                            newHost = m_originalUnicodeString.Substring(0, startInput) + userInfoString + idnValue;
-                            flags |= Flags.CanonicalDnsHost;
-                            m_DnsSafeHost = new string(pString, start, end - start);
-                            justNormalized = true;
-                        }
-                        flags |= Flags.HostUnicodeNormalized;
-                    }
-                }
-            }
-            else if (((syntaxFlags & UriSyntaxFlags.AllowDnsHost) != 0)
-                    && ((syntax.InFact(UriSyntaxFlags.AllowIriParsing) && hostNotUnicodeNormalized)
-                            || syntax.InFact(UriSyntaxFlags.AllowIdn))
-                    && DomainNameHelper.IsValidByIri(pString, start, ref end, ref dnsNotCanonical,
-                                            StaticNotAny(flags, Flags.ImplicitFile)))
-            {
-                CheckAuthorityHelperHandleDnsIri(pString, start, end, startInput, iriParsing, hasUnicode, syntax, 
-                    userInfoString, ref flags, ref justNormalized, ref newHost, ref err);
-            }
-#if !PLATFORM_UNIX
-            else if ((syntaxFlags & UriSyntaxFlags.AllowUncHost) != 0)
-            {
-                //
-                // This must remain as the last check befor BasicHost type
-                //
-                if (UncNameHelper.IsValid(pString, start, ref end, StaticNotAny(flags, Flags.ImplicitFile)))
-                {
-                    if (end - start <= UncNameHelper.MaximumInternetNameLength)
-                    {
-                        flags |= Flags.UncHostType;
-                        if (hasUnicode && iriParsing && hostNotUnicodeNormalized)
-                        {
-                            newHost += new string(pString, start, end - start);
-                            flags |= Flags.HostUnicodeNormalized;
-                            justNormalized = true;
-                        }
-                    }
-                }
-            }
-#endif // !PLATFORM_UNIX
-
-            // The deal here is that we won't allow '\' host terminator except for the File scheme
-            // If we see '\' we try to make it a part of of a Basic host
-            if (end < length && pString[end] == '\\' && (flags & Flags.HostTypeMask) != Flags.HostNotParsed 
-                && !StaticIsFile(syntax))
-            {
-                if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri))
-                {
-                    err = ParsingError.BadHostName;
-                    flags |= Flags.UnknownHostType;
-                    return (ushort) end;
-                }
-                flags &= ~Flags.HostTypeMask;
-            }
-            // Here we have checked the syntax up to the end of host
-            // The only thing that can cause an exception is the port value
-            // Spend some (duplicated) cycles on that.
-            else if (end < length && pString[end] == ':')
-            {
-                if (syntax.InFact(UriSyntaxFlags.MayHavePort))
-                {
-                    int port = 0;
-                    int startPort = end;
-                    for (idx = (ushort)(end+1); idx < length; ++idx) {
-                        ushort val = (ushort)((ushort)pString[idx] - (ushort)'0');
-                        if ((val >= 0) && (val <= 9))
-                        {
-                            if ((port = (port * 10 + val)) > 0xFFFF)
-                                break;
-                        }
-                        else if (val == unchecked((ushort)('/' - '0')) || val == (ushort)('?' - '0') 
-                            || val == unchecked((ushort)('#' - '0')))
-                        {
-                            break;
-                        }
-                        else
-                        {
-                            // The second check is to keep compatibility with V1 until the UriParser is registered
-                            if(syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost) 
-                                && syntax.NotAny(UriSyntaxFlags.V1_UnknownUri))
-                            {
-                                flags &= ~Flags.HostTypeMask;
-                                break;
-                            }
-                            else
-                            {
-                                err = ParsingError.BadPort;
-                                return idx;
-                            }
-                        }
-                    }
-                    // check on 0-ffff range
-                    if (port > 0xFFFF)
-                    {
-                        if (syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost))
-                        {
-                            flags &= ~Flags.HostTypeMask;
-                        }
-                        else
-                        {
-                            err = ParsingError.BadPort;
-                            return idx;
-                        }
-                    }
-
-                    if (iriParsing && hasUnicode && justNormalized){
-                        newHost += new string(pString, startPort, idx - startPort);
-                    }
-                }
-                else
-                {
-                    flags &= ~Flags.HostTypeMask;
-                }
-
-            }
-
-            // check on whether nothing has worked out
-            if ((flags & Flags.HostTypeMask) == Flags.HostNotParsed)
-            {
-                //No user info for a Basic hostname
-                flags &= ~Flags.HasUserInfo;
-                // Some schemes do not allow HostType = Basic (plus V1 almost never understands this cause of a bug)
-                //
-                if(syntax.InFact(UriSyntaxFlags.AllowAnyOtherHost))
-                {
-                    flags |= Flags.BasicHostType;
-                    for (end = idx; end < length; ++end) {
-                        if (pString[end] == '/' || (pString[end] == '?' || pString[end] == '#')) {
-                            break;
-                        }
-                    }
-                    CheckAuthorityHelperHandleAnyHostIri(pString, startInput, end, iriParsing, hasUnicode, syntax,
-                                                            ref flags, ref newHost, ref err);
-                }
-                else
-                {
-                    //
-                    // ATTN V1 compat: V1 supports hostnames like ".." and ".", and so we do but only for unknown schemes.
-                    //                 (VsWhidbey#438821)
-                    if (syntax.InFact(UriSyntaxFlags.V1_UnknownUri))
-                    {
-                        // Can assert here that the host is not empty so we will set dotFound
-                        // at least once or fail before exiting the loop
-                        bool dotFound = false;
-                        int startOtherHost = idx;
-                        for (end = idx; end < length; ++end)
-                        {
-                            if (dotFound && (pString[end] == '/' || pString[end] == '?' || pString[end] == '#'))
-                                break;
-                            else if (end < (idx + 2) && pString[end] == '.')
-                            {
-                                // allow one or two dots
-                                dotFound = true;
-                            }
-                            else
-                            {
-                                //failure
-                                err = ParsingError.BadHostName;
-                                flags |= Flags.UnknownHostType;
-                                return idx;
-                            }
-                        }
-                        //success
-                        flags |= Flags.BasicHostType;
-
-                        if (iriParsing && hasUnicode
-                            && StaticNotAny(flags, Flags.HostUnicodeNormalized)){
-                            // Normalize any other host
-                            String user = new string(pString, startOtherHost, end - startOtherHost);
-                            try
-                            {
-                                newHost += user.Normalize(NormalizationForm.FormC);
-                            }
-                            catch (ArgumentException){
-                                err = ParsingError.BadFormat;
-                                return idx;
-                            }
-
-                            flags |= Flags.HostUnicodeNormalized;
-                        }
-                    }
-                    else if (syntax.InFact(UriSyntaxFlags.MustHaveAuthority) ||
-                             (syntax.InFact(UriSyntaxFlags.MailToLikeUri) && !UriParser.ShouldUseLegacyV2Quirks))
-                    {
-                        err = ParsingError.BadHostName;
-                        flags |= Flags.UnknownHostType;
-                        return idx;
-                    }
-                }
-            }
-            return (ushort) end;
-        }
-
-        unsafe void CheckAuthorityHelperHandleDnsIri( char* pString, ushort start, int end, int startInput,
-            bool iriParsing, bool hasUnicode, UriParser syntax, string userInfoString, ref Flags flags, 
-            ref bool justNormalized, ref string newHost, ref ParsingError err)
-        {
-            // comes here only if host has unicode chars and iri is on or idn is allowed
-
-            flags |= Flags.DnsHostType;
-
-            // check if intranet
-            //
-            if ((s_IdnScope == UriIdnScope.AllExceptIntranet) && IsIntranet(new string(pString, 0, end)))
-            {
-                flags |= Flags.IntranetUri;
-            }
-
-            if (AllowIdnStatic(syntax, flags))
-            {
-                bool allAscii = true;
-                bool atLeastOneIdn = false;
-
-                string idnValue = DomainNameHelper.IdnEquivalent(pString, start, end, ref allAscii, ref atLeastOneIdn);
-                string UniEquvlt = DomainNameHelper.UnicodeEquivalent(idnValue, pString, start, end);
-
-                if (!allAscii)
-                    flags |= Flags.UnicodeHost; // we have a unicode host
-
-                if (atLeastOneIdn)
-                    flags |= Flags.IdnHost;   // we have at least one valid idn label
-
-                if (allAscii && atLeastOneIdn && StaticNotAny(flags, Flags.HasUnicode))
-                {
-                    // original string location changed lazily
-                    m_originalUnicodeString = m_String;
-                    newHost = m_originalUnicodeString.Substring(0, startInput) +
-                        (StaticInFact(flags, Flags.HasUserInfo) ? userInfoString : null);
-                    justNormalized = true;
-                }
-                else if (!iriParsing && (StaticInFact(flags, Flags.UnicodeHost) || StaticInFact(flags, Flags.IdnHost)))
-                {
-                    // original string location changed lazily
-                    m_originalUnicodeString = m_String;
-                    newHost = m_originalUnicodeString.Substring(0, startInput) +
-                        (StaticInFact(flags, Flags.HasUserInfo) ? userInfoString : null);
-                    justNormalized = true;
-                }
-
-                if (!(allAscii && !atLeastOneIdn))
-                {
-                    m_DnsSafeHost = idnValue;
-                    newHost += UniEquvlt;
-                    justNormalized = true;
-                }
-                else if (allAscii && !atLeastOneIdn && iriParsing && hasUnicode)
-                {
-                    newHost += UniEquvlt;
-                    justNormalized = true;
-                }
-            }
-            else
-            {
-                if (hasUnicode)
-                {
-                    string temp = StripBidiControlCharacter(pString, start, end - start);
-                    try{
-                        newHost += ((temp != null) ? temp.Normalize(NormalizationForm.FormC) : null);
-                    }
-                    catch (ArgumentException){
-                        err = ParsingError.BadHostName;
-                    }
-                    justNormalized = true;
-                }
-            }
-            flags |= Flags.HostUnicodeNormalized;
-        }
-
-        unsafe void CheckAuthorityHelperHandleAnyHostIri(char* pString, int startInput, int end,
-                                            bool iriParsing, bool hasUnicode, UriParser syntax,
-                                            ref Flags flags, ref string newHost, ref ParsingError err)
-        {
-            if (StaticNotAny(flags, Flags.HostUnicodeNormalized) && (AllowIdnStatic(syntax, flags) || 
-                (iriParsing && hasUnicode)))
-            {
-                // Normalize any other host or do idn
-                String user = new string(pString, startInput, end - startInput);
-
-                if (AllowIdnStatic(syntax, flags))
-                {
-                    bool allAscii = true;
-                    bool atLeastOneIdn = false;
-
-                    string UniEquvlt = DomainNameHelper.UnicodeEquivalent(pString, startInput, end, ref allAscii, 
-                        ref atLeastOneIdn);
-
-                    if (((allAscii && atLeastOneIdn) || !allAscii) && !(iriParsing && hasUnicode))
-                    {
-                        // original string location changed lazily
-                        m_originalUnicodeString = m_String;
-                        newHost = m_originalUnicodeString.Substring(0, startInput);
-                        flags |= Flags.HasUnicode;
-                    }
-                    if (atLeastOneIdn || !allAscii)
-                    {
-                        newHost += UniEquvlt;
-                        string bidiStrippedHost = null;
-                        m_DnsSafeHost = DomainNameHelper.IdnEquivalent(pString, startInput, end, ref  allAscii, 
-                            ref bidiStrippedHost);
-                        if (atLeastOneIdn)
-                            flags |= Flags.IdnHost;
-                        if (!allAscii)
-                            flags |= Flags.UnicodeHost;
-                    }
-                    else if (iriParsing && hasUnicode)
-                    {
-                        newHost += user;
-
-                    }
-                }
-                else
-                {
-                    try{
-                        newHost += user.Normalize(NormalizationForm.FormC);
-                    }
-                    catch (ArgumentException){
-                        err = ParsingError.BadHostName;
-                    }
-                }
-
-                flags |= Flags.HostUnicodeNormalized;
-            }
-        }
-
-        //
-        //
-        // The method checks whether a string needs transformation before going to display or wire
-        //
-        // Parameters:
-        // - escaped   true = treat all valid escape sequences as escaped sequences, false = escape all %
-        // - delim     a character signalling the termination of the component being checked
-        //
-        // When delim=='?', then '#' character is also considered as delimiter additionally to passed '?'.
-        //
-        // The method pays attention to the dots and slashes so to signal potential Path compression action needed.
-        // Even that is not required for other components, the cycles are still spent (little inefficiency)
-        //
-
-        internal const char c_DummyChar = (char) 0xFFFF;     //An Invalid Unicode character used as a dummy char passed into the parameter
-        internal const char c_EOL       = (char) 0xFFFE;     //An Invalid Unicode character used by CheckCanonical as "no delimiter condition"
-        [Flags]
-        private enum Check {
-            None            = 0x0,
-            EscapedCanonical= 0x1,
-            DisplayCanonical= 0x2,
-            DotSlashAttn    = 0x4,
-            DotSlashEscaped = 0x80,
-            BackslashInPath = 0x10,
-            ReservedFound   = 0x20,
-            NotIriCanonical = 0x40,
-            FoundNonAscii =    0x8
-        }
-
-        //
-        // Finds the end of component
-        //
-
-        private unsafe void FindEndOfComponent(string input, ref ushort idx, ushort end, char delim)
-        {
-            fixed (char* str = input)
-            {
-                FindEndOfComponent(str, ref idx, end, delim);
-            }
-        }
-        private unsafe void FindEndOfComponent(char* str, ref ushort idx, ushort end, char delim)
-        {
-            char c = c_DummyChar;
-            ushort i=idx;
-            for (; i < end; ++i)
-            {
-                c = str[i];
-                if (c == delim)
-                {
-                    break;
-                }
-                else if (delim == '?' && c == '#' && (m_Syntax != null && m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment)))
-                {
-                    // this is a special case when deciding on Query/Fragment
-                    break;
-                }
-            }
-            idx = i;
-        }
-
-        //
-        // Used by ParseRemaining as well by InternalIsWellFormedOriginalString
-        //
-        private unsafe Check CheckCanonical(char* str, ref ushort idx, ushort end, char delim) {
-            Check res = Check.None;
-            bool needsEscaping = false;
-            bool foundEscaping = false;
-
-            char c = c_DummyChar;
-            ushort i=idx;
-            for (; i < end; ++i)
-            {
-                c = str[i];
-                // Control chars usually should be escaped in any case
-                if (c <= '\x1F' || (c >= '\x7F' && c <= '\x9F'))
-                {
-                    needsEscaping = true;
-                    foundEscaping = true;
-                    res |= Check.ReservedFound;
-                }
-                else if (c > 'z' && c != '~') {
-                    if(m_iriParsing){
-                        bool valid = false;
-                        res |= Check.FoundNonAscii;
-
-                        if (Char.IsHighSurrogate(c)){
-                            if ((i + 1) < end){
-                                bool surrPair = false;
-                                valid = IriHelper.CheckIriUnicodeRange(c, str[i + 1], ref surrPair, true);
-                            }
-                        }
-                        else{
-                            valid = IriHelper.CheckIriUnicodeRange(c, true);
-                        }
-                        if (!valid) res |= Check.NotIriCanonical;
-                    }
-
-                    if (!needsEscaping) needsEscaping = true;
-                }
-                else if (c == delim) {
-                    break;
-                }
-                else if (delim == '?' && c == '#' && (m_Syntax != null && m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment))) {
-                    // this is a special case when deciding on Query/Fragment
-                    break;
-                }
-                else if (c == '?') {
-                    if (IsImplicitFile || (m_Syntax != null && !m_Syntax.InFact(UriSyntaxFlags.MayHaveQuery) 
-                        && delim != c_EOL))
-                    {
-                        // VsWhidbey#87423
-                        // If found as reserved this char is not suitable for safe unescaped display
-                        // Will need to escape it when both escaping and unescaping the string
-                        res |= Check.ReservedFound;
-                        foundEscaping = true;
-                        needsEscaping = true;
-                    }
-                }
-                else if (c == '#') {
-                    needsEscaping = true;
-                    if (IsImplicitFile || (m_Syntax != null && !m_Syntax.InFact(UriSyntaxFlags.MayHaveFragment))) {
-                        // VsWhidbey#87423, 122037
-                        // If found as reserved this char is not suitable for safe unescaped display
-                        // Will need to escape it when both escaping and unescaping the string
-                        res |= Check.ReservedFound;
-                        foundEscaping = true;
-                    }
-                }
-                else if (c == '/' || c == '\\') {
-                    if ((res & Check.BackslashInPath) == 0 && c == '\\') {
-                        res |= Check.BackslashInPath;
-                    }
-                    if ((res & Check.DotSlashAttn) == 0 && i+1 != end && (str[i+1] == '/' || str[i+1] == '\\' )) {
-                        res |= Check.DotSlashAttn;
-                    }
-                }
-                else if (c == '.') {
-                    if ((res & Check.DotSlashAttn) == 0 && i+1 == end || str[i+1] == '.' || str[i+1] == '/' 
-                        || str[i+1] == '\\' || str[i+1] == '?' || str[i+1] == '#') {
-                        res |= Check.DotSlashAttn;
-                    }
-                }
-                else if (!needsEscaping && ((c <= '"' && c != '!') || (c >= '[' && c <= '^') || c == '>' 
-                    || c == '<' || c == '`')) {
-                    needsEscaping = true;
-                }
-                else if (c == '%') {
-                    if (!foundEscaping) foundEscaping = true;
-                    //try unescape a byte hex escaping
-                    if (i + 2 < end && (c = UriHelper.EscapedAscii(str[i + 1], str[i + 2])) != c_DummyChar)
-                    {
-                        if (c == '.' || c == '/' || c == '\\') {
-                            res |= Check.DotSlashEscaped;
-                        }
-                        i+=2;
-                        continue;
-                    }
-                    // otherwise we follow to non escaped case
-                    if (!needsEscaping) {
-                        needsEscaping = true;
-                    }
-                }
-            }
-
-            if (foundEscaping) {
-                if (!needsEscaping) {
-                    res |= Check.EscapedCanonical;
-                }
-            }
-            else {
-                res |= Check.DisplayCanonical;
-                if (!needsEscaping) {
-                    res |= Check.EscapedCanonical;
-                }
-            }
-            idx = i;
-            return res;
-        }
-
-        //
-        // Returns the escaped and canonicalized path string
-        // the passed array must be long enough to hold at least
-        // canonical unescaped path representation (allocated by the caller)
-        //
-        private unsafe char[] GetCanonicalPath(char[] dest, ref int pos, UriFormat formatAs)
-        {
-
-            if (InFact(Flags.FirstSlashAbsent))
-                dest[pos++] = '/';
-
-            if (m_Info.Offset.Path == m_Info.Offset.Query)
-                return dest;
-
-            int end = pos;
-
-            int dosPathIdx = SecuredPathIndex;
-
-            // Note that unescaping and then escapig back is not transitive hence not safe.
-            // We are vulnerable due to the way the UserEscaped flag is processed (see NDPWhidbey#10612 bug).
-            // Try to unescape only needed chars.
-            if (formatAs == UriFormat.UriEscaped)
-            {
-                if (InFact(Flags.ShouldBeCompressed))
-                {
-                    m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path);
-                    end += (m_Info.Offset.Query - m_Info.Offset.Path);
-
-                    // If the path was found as needed compression and contains escaped characters, unescape only 
-                    // interesting characters (safe)
-
-                    if (m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes) && InFact(Flags.PathNotCanonical) 
-                        && !IsImplicitFile)
-                    {
-                        fixed (char* pdest = dest)
-                        {
-                            UnescapeOnly(pdest, pos, ref end, '.', '/', 
-                                m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) ? '\\' : c_DummyChar);
-                        }
-                    }
-                }
-                else
-                {
-                    //
-                    if (InFact(Flags.E_PathNotCanonical) && NotAny(Flags.UserEscaped)) {
-                        string str = m_String;
-
-                        // Check on not canonical disk designation like C|\, should be rare, rare case
-                        if (dosPathIdx != 0 && str[dosPathIdx + m_Info.Offset.Path -1] == '|')
-                        {
-                            str = str.Remove(dosPathIdx + m_Info.Offset.Path -1, 1);
-                            str = str.Insert(dosPathIdx + m_Info.Offset.Path -1, ":");
-                        }
-                        dest = UriHelper.EscapeString(str, m_Info.Offset.Path, m_Info.Offset.Query, dest, ref end, true, 
-                            '?', '#', IsImplicitFile? c_DummyChar: '%');
-                    }
-                    else {
-                        m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path);
-                        end += (m_Info.Offset.Query - m_Info.Offset.Path);
-                    }
-                }
-            }
-            else
-            {
-                m_String.CopyTo(m_Info.Offset.Path, dest, end, m_Info.Offset.Query - m_Info.Offset.Path);
-                end += (m_Info.Offset.Query - m_Info.Offset.Path);
-
-                if (InFact(Flags.ShouldBeCompressed))
-                {
-                    // If the path was found as needed compression and contains escaped characters, 
-                    // unescape only interesting characters (safe)
-
-                    if (m_Syntax.InFact(UriSyntaxFlags.UnEscapeDotsAndSlashes) && InFact(Flags.PathNotCanonical) 
-                        && !IsImplicitFile)
-                    {
-                        fixed (char* pdest = dest)
-                        {
-                            UnescapeOnly(pdest, pos, ref end, '.', '/', 
-                                m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) ? '\\' : c_DummyChar);
-                        }
-                    }
-                }
-            }
-
-            // Here we already got output data as copied into dest array
-            // We just may need more processing of that data
-
-            //
-            // if this URI is using 'non-proprietary' disk drive designation, convert to MS-style
-            //
-            // (path is already  >= 3 chars if recognized as a DOS-like)
-            //
-            if (dosPathIdx != 0 && dest[dosPathIdx + pos - 1] == '|')
-                dest[dosPathIdx + pos - 1] = ':';
-
-            if (InFact(Flags.ShouldBeCompressed))
-            {
-                // It will also convert back slashes if needed
-                dest = Compress(dest, (ushort)(pos + dosPathIdx), ref end, m_Syntax);
-                if (dest[pos] == '\\')
-                    dest[pos] = '/';
-
-                // Escape path if requested and found as not fully escaped
-                if (formatAs == UriFormat.UriEscaped && NotAny(Flags.UserEscaped) && InFact(Flags.E_PathNotCanonical)) {
-                    //
-                    string srcString = new string(dest, pos, end-pos);
-                    dest = UriHelper.EscapeString(srcString, 0, end - pos, dest, ref pos, true, '?', '#', 
-                        IsImplicitFile ? c_DummyChar : '%');
-                    end = pos;
-                }
-            }
-            else if (m_Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes) && InFact(Flags.BackslashInPath))
-            {
-                for (int i = pos; i < end; ++i)
-                    if (dest[i] == '\\') dest[i] = '/';
-            }
-
-            if (formatAs != UriFormat.UriEscaped && InFact(Flags.PathNotCanonical))
-            {
-                UnescapeMode mode;
-                if (InFact(Flags.PathNotCanonical))
-                {
-                    switch (formatAs)
-                    {
-                    case V1ToStringUnescape:
-
-                        mode = (InFact(Flags.UserEscaped) ? UnescapeMode.Unescape : UnescapeMode.EscapeUnescape) 
-                            | UnescapeMode.V1ToStringFlag;
-                        if (IsImplicitFile)
-                            mode &= ~UnescapeMode.Unescape;
-                        break;
-
-                    case UriFormat.Unescaped:
-                        mode = IsImplicitFile ? UnescapeMode.CopyOnly 
-                            : UnescapeMode.Unescape | UnescapeMode.UnescapeAll;
-                        break;
-
-                    default: // UriFormat.SafeUnescaped
-
-                        mode = InFact(Flags.UserEscaped)? UnescapeMode.Unescape: UnescapeMode.EscapeUnescape;
-                        if (IsImplicitFile)
-                            mode &= ~UnescapeMode.Unescape;
-                        break;
-                    }
-                }
-                else {
-                    mode = UnescapeMode.CopyOnly;
-                }
-
-                char[] dest1 = new char[dest.Length];
-                Buffer.BlockCopy(dest, 0, dest1, 0, end<<1);
-                fixed (char *pdest = dest1)
-                {
-                    dest = UriHelper.UnescapeString(pdest, pos, end, dest, ref pos, '?', '#', c_DummyChar, mode, 
-                        m_Syntax, false);
-                }
-            }
-            else
-            {
-                pos = end;
-            }
-
-            return dest;
-        }
-
-        // works only with ASCII characters, used to partially unescape path before compressing
-        private unsafe static void UnescapeOnly(char* pch, int start, ref int end, char ch1, char ch2, char ch3) {
-            if (end - start < 3) {
-                //no chance that something is escaped
-                return;
-            }
-
-            char *pend = pch + end-2;
-            pch += start;
-            char *pnew = null;
-
-            over:
-
-            // Just looking for a interested escaped char
-            if (pch >= pend)    goto done;
-            if(*pch++ != '%')   goto over;
-
-            char ch = UriHelper.EscapedAscii(*pch++, *pch++);
-            if (!(ch == ch1 || ch == ch2 || ch == ch3)) goto over;
-
-            // Here we found something and now start copying the scanned chars
-            pnew = pch-2;
-            *(pnew-1) = ch;
-
-            over_new:
-
-            if (pch >= pend)                goto done;
-            if((*pnew++ = *pch++) != '%')   goto over_new;
-
-            ch = UriHelper.EscapedAscii((*pnew++ = *pch++), (*pnew++ = *pch++));
-            if (!(ch == ch1 || ch == ch2 || ch == ch3)) {
-                goto over_new;
-            }
-
-            pnew -= 2;
-            *(pnew-1) = ch;
-
-            goto over_new;
-
-            done:
-            pend+=2;
-
-            if (pnew == null) {
-                //nothing was found
-                return;
-            }
-
-            //the tail may be already processed
-            if(pch == pend) {
-                end -= (int) (pch-pnew);
-                return;
-            }
-
-            *pnew++ = *pch++;
-            if(pch == pend) {
-                end -= (int) (pch-pnew);
-                return;
-            }
-            *pnew++ = *pch++;
-            end -= (int) (pch-pnew);
-        }
-
-        //
-        //
-        // This will compress any "\" "/../" "/./" "///" "/..../" /XXX.../, etc found in the input
-        //
-        // The passed syntax controls whether to use agressive compression or the one specified in RFC 2396
-        //
-        //
-        private static char[] Compress(char[] dest, ushort start, ref int destLength, UriParser syntax)
-        {
-            ushort  slashCount      = 0;
-            ushort  lastSlash       = 0;
-            ushort  dotCount        = 0;
-            ushort  removeSegments  = 0;
-
-            unchecked {
-                //ushort i == -1 and start == -1 overflow is ok here
-                ushort  i = (ushort)((ushort)destLength - (ushort)1);
-                start = (ushort)(start-1);
-
-                for (; i != start ; --i) {
-                    char ch = dest[i];
-                    if (ch == '\\' && syntax.InFact(UriSyntaxFlags.ConvertPathSlashes)) {
-                        dest[i] = ch = '/';
-                    }
-
-                    //
-                    // compress multiple '/' for file URI
-                    //
-                    if (ch == '/') {
-                        ++slashCount;
-                        /*
-                        QFE 4390 - remove the compression of multiple slashes to a single slash
-                        if (slashCount > 1) {
-                            continue;
-                        }
-			*/
-                    }
-                    else {
-                        if (slashCount > 1) {
-                            /*
-                            QFE 4390 - remove the compression of multiple slashes to a single slash
-                            if (syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath))
-                            {
-                                // We saw > 1 slashes so remove all but the last one
-                                // dest.Remove(i+1, slashCount -1);
-                                Buffer.BlockCopy(dest, (i + slashCount) << 1, dest, (i + 1) << 1, 
-                                    (destLength - (i + slashCount)) << 1);
-                                destLength -= (slashCount - 1);
-                            }
-			    */
-                            // else preserve repeated slashes
-                            lastSlash = (ushort)(i + 1);
-                        }
-                        slashCount = 0;
-                    }
-
-                    if (ch == '.') {
-                        ++dotCount;
-                        continue;
-                    }
-                    else if (dotCount != 0) {
-
-                        bool skipSegment = syntax.NotAny(UriSyntaxFlags.CanonicalizeAsFilePath) 
-                            && (dotCount > 2 || ch != '/' || i == start);
-
-                        //
-                        // Cases:
-                        // /./                  = remove this segment 
-                        // /../                 = remove this segment, mark next for removal
-                        // /....x               = DO NOT TOUCH, leave as is
-                        // x.../                = DO NOT TOUCH, leave as is, except for V2 legacy mode
-                        //
-                        if (!skipSegment && ch == '/') {
-                            if ((lastSlash == i + dotCount + 1 // "/..../"
-                                    || (lastSlash == 0 && i + dotCount + 1 == destLength)) // "/..."
-                                && (UriParser.ShouldUseLegacyV2Quirks || dotCount <= 2)) {
-                                //
-                                //  /./ or /.<eos> or /../ or /..<eos>
-                                //
-                                // just reusing a variable slot we perform //dest.Remove(i+1, dotCount + (lastSlash==0?0:1));
-                                lastSlash = (ushort)(i + 1 + dotCount + (lastSlash==0?0:1));
-                                Buffer.BlockCopy(dest, lastSlash<<1, dest, (i+1)<<1, (destLength - lastSlash)<<1);
-                                destLength -= (lastSlash-i-1);
-
-                                lastSlash = i;
-                                if (dotCount == 2) {
-                                    //
-                                    // We have 2 dots in between like /../ or /..<eos>,
-                                    // Mark next segment for removal and remove this /../ or /..
-                                    //
-                                    ++removeSegments;
-                                }
-                                dotCount = 0;
-                                continue;
-                            }
-                        }
-                        else if (UriParser.ShouldUseLegacyV2Quirks
-                            && !skipSegment
-                            && (removeSegments == 0) 
-                            && (lastSlash == i+dotCount+1 || (lastSlash == 0 && i+dotCount+1 == destLength))) {
-                            //
-                            // Note if removeSegments!=0, then ignore and remove the whole segment later
-                            //
-                            // x.../  or  x...<eos>
-                            // remove trailing dots
-                            //
-                            //
-                            // just reusing a variable slot we perform //dest.Remove(i+1, dotCount);
-                            dotCount = (ushort)(i + 1 + dotCount);
-                            Buffer.BlockCopy(dest, dotCount<<1, dest, (i+1)<<1, (destLength - dotCount)<<1);
-                            destLength -= (dotCount-i-1);
-                            lastSlash = 0;  //the other dots in this segment will stay intact
-                            dotCount = 0;
-                            continue;
-                        }
-                            // .NET 4.5 no longer removes trailing dots in a path segment x.../  or  x...<eos>
-                            dotCount = 0;
-                        
-                        //
-                        // Here all other cases go such as
-                        // x.[..]y or /.[..]x or (/x.[...][/] && removeSegments !=0)
-                    }
-
-                    //
-                    // Now we may want to remove a segment because of previous /../
-                    //
-                    if (ch == '/') {
-                        if (removeSegments  != 0) {
-                            --removeSegments;
-
-                            // just reusing a variable slot we perform //dest.Remove(i+1, lastSlash - i);
-                            lastSlash = (ushort)(lastSlash + 1);
-                            Buffer.BlockCopy(dest, lastSlash<<1, dest, (i+1)<<1, (destLength - lastSlash)<<1);
-                            destLength -= (lastSlash-i-1);
-                        }
-                    lastSlash = i;
-                    }
-                }
-
-               start = (ushort)((ushort)start + (ushort)1);
-            } //end of unchecked
-
-            // Dead Code?
-            if ((ushort)destLength > start && syntax.InFact(UriSyntaxFlags.CanonicalizeAsFilePath))
-            {
-                if (slashCount > 1) {
-		    /*
-                    Buffer.BlockCopy(dest, lastSlash << 1, dest, start << 1, (destLength - lastSlash) << 1);
-                    destLength -= (slashCount - 1);
-                    */
-                    //QFE 4390 - Fall through for compat after not multiple slashes to a single slashl
-                }
-                else if (removeSegments != 0 && dest[start] != '/') {
-                    //remove first not rooted segment
-                    // dest.Remove(i+1, lastSlash - i);
-                    lastSlash = (ushort)(lastSlash + 1);
-                    Buffer.BlockCopy(dest, lastSlash<<1, dest, start<<1, (destLength - lastSlash)<<1);
-                    destLength -= lastSlash;
-                }
-                else if (dotCount != 0) {
-                    // If final string starts with a segment looking like .[...]/ or .[...]<eos>
-                    // then we remove this fisrt segment
-                    if (lastSlash == dotCount+1 || (lastSlash == 0 && dotCount + 1 == destLength)) {
-                        //dest.Remove(0, dotCount + (lastSlash==0?0:1));
-                        dotCount = (ushort)(dotCount + (lastSlash==0?0:1));
-                        Buffer.BlockCopy(dest, dotCount<<1, dest, start<<1, (destLength - dotCount)<<1);
-                        destLength -= dotCount;
-                    }
-                }
-            }
-            return dest;
-        }
-
-        //used by DigestClient
-        internal static readonly char[] HexLowerChars = {
-                                   '0', '1', '2', '3', '4', '5', '6', '7',
-                                   '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-                                   };
-
-        internal static int CalculateCaseInsensitiveHashCode(string text)
-        {
-            return StringComparer.InvariantCultureIgnoreCase.GetHashCode(text);
-        }
-        //
-        // CombineUri
-        //
-        //  Given 2 URI strings, combine them into a single resultant URI string
-        //
-        // Inputs:
-        //  <argument>  basePart
-        //      Base URI to combine with
-        //
-        //  <argument>  relativePart
-        //      String expected to be relative URI
-        //
-        // Assumes:
-        //  <basePart> is in canonic form
-        //
-        // Returns:
-        //  Resulting combined URI string
-        //
-        private static string CombineUri(Uri basePart, string relativePart, UriFormat uriFormat) {
-           //NB: relativePart is ensured as not empty by the caller
-           //    Another assumption is that basePart is an AbsoluteUri
-
-           // This method was not optimized for efficiency
-           // Means a relative Uri ctor may be relatively slow plus it increases the footprint of the baseUri
-
-           char c1 = relativePart[0];
-
-#if !PLATFORM_UNIX
-           //check a special case for the base as DOS path and a rooted relative string
-           if ( basePart.IsDosPath &&
-               (c1 == '/' || c1 == '\\') &&
-               (relativePart.Length == 1 || (relativePart[1] != '/' && relativePart[1] != '\\')))
-           {
-               // take relative part appended to the base string after the drive letter
-               int idx = basePart.OriginalString.IndexOf(':');
-               if (basePart.IsImplicitFile) {
-                   return basePart.OriginalString.Substring(0, idx+1 ) + relativePart;
-               }
-               // The basePart has explicit scheme (could be not file:), take the DOS drive ':' position
-               idx = basePart.OriginalString.IndexOf(':', idx+1);
-               return basePart.OriginalString.Substring(0, idx+1 ) + relativePart;
-           }
-#endif // !PLATFORM_UNIX
-
-           // Check special case for Unc or absolute path in relativePart when base is FILE
-           if (StaticIsFile(basePart.Syntax))
-           {
-
-                if (c1 == '\\' || c1 == '/') {
-
-                    if(relativePart.Length >= 2 && (relativePart[1] == '\\' || relativePart[1] == '/')) {
-                        //Assuming relative is a Unc path and base is a file uri.
-                        return basePart.IsImplicitFile? relativePart: "file:" + relativePart;
-                    }
-
-                    // here we got an absolute path in relativePart,
-                    // For compatibility with V1.0 parser we restrict the compression scope to Unc Share, i.e. \\host\share\
-                    if (basePart.IsUnc) {
-                        string share = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter, 
-                            UriFormat.Unescaped);
-                        for (int i = 1; i < share.Length; ++i) {
-                            if (share[i] == '/') {
-                                share = share.Substring(0, i);
-                                break;
-                            }
-                        }
-                        if (basePart.IsImplicitFile) {
-                            return  @"\\"
-                                    + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped)
-                                    + share
-                                    + relativePart;
-                        }
-                        return  "file://"
-                                + basePart.GetParts(UriComponents.Host, uriFormat)
-                                + share
-                                + relativePart;
-
-                    }
-                    // It's not obvious but we've checked (for this relativePart format) that baseUti is nor UNC nor DOS path
-                    //
-                    // Means base is a Unix style path and, btw, IsImplicitFile cannot be the case either
-                    return "file://" + relativePart;
-               }
-           }
-
-           // If we are here we did not recognize absolute DOS/UNC path for a file: base uri
-           // Note that DOS path may still happen in the relativePart and if so it may override the base uri scheme.
-
-           bool convBackSlashes =  basePart.Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes);
-
-           string left = null;
-
-           // check for network or local absolute path
-           if (c1 == '/' || (c1 == '\\' && convBackSlashes)) {
-               if (relativePart.Length >= 2 && relativePart[1] == '/') {
-                   // got an authority in relative path and the base scheme is not file (checked)
-                   return basePart.Scheme + ':' + relativePart;
-               }
-
-               // Got absolute relative path, and the base is nor FILE nor a DOS path (checked at the method start)
-               if (basePart.HostType == Flags.IPv6HostType) {
-                   left =  basePart.GetParts(UriComponents.Scheme|UriComponents.UserInfo, uriFormat)
-                                    + '[' + basePart.DnsSafeHost + ']'
-                                    + basePart.GetParts(UriComponents.KeepDelimiter|UriComponents.Port, uriFormat);
-               }
-               else {
-                   left =  basePart.GetParts(UriComponents.SchemeAndServer|UriComponents.UserInfo, uriFormat);
-               }
-               //VsWhidbey#241426
-               if (convBackSlashes && c1 == '\\')
-                   relativePart = '/' + relativePart.Substring(1);
-
-               return left + relativePart;
-           }
-
-           // Here we got a relative path
-           // Need to run path Compression because this is how relative Uri combining works
-
-           // Take the base part path up to and including the last slash
-           left = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter, 
-               basePart.IsImplicitFile ? UriFormat.Unescaped : uriFormat);
-           int length = left.Length;
-           char[] path = new char[length + relativePart.Length];
-
-           if (length > 0) {
-               left.CopyTo(0, path, 0, length);
-               while(length > 0) {
-                   if (path[--length] == '/') {
-                       ++length;
-                       break;
-                   }
-               }
-           }
-
-           //Append relative path to the result
-           relativePart.CopyTo(0, path, length, relativePart.Length);
-
-           // Split relative on path and extra (for compression)
-           c1 = basePart.Syntax.InFact(UriSyntaxFlags.MayHaveQuery)? '?': c_DummyChar;
-
-           // The  implcit file check is to avoid a fragment in the implicit file combined uri.
-           // The behavior change request is tracked vis VsWhidbey#261387 ans that was approved through VsWhidbey#266417.
-           char c2 = (!basePart.IsImplicitFile && basePart.Syntax.InFact(UriSyntaxFlags.MayHaveFragment)) ? '#' : 
-               c_DummyChar;
-           string extra = String.Empty;
-
-           // assuming c_DummyChar may not happen in an unicode uri string
-           if (!(c1 == c_DummyChar && c2 == c_DummyChar)) {
-               int i=0;
-               for (;i < relativePart.Length; ++i) {
-                   if (path[length + i] == c1 || path[length + i] == c2) {
-                       break;
-                   }
-               }
-               if (i == 0) {
-                   extra = relativePart;
-               }
-               else if (i < relativePart.Length) {
-                   extra = relativePart.Substring(i);
-               }
-               length += i;
-           }
-           else {
-               length += relativePart.Length;
-           }
-
-           // Take the base part up to the path
-           if (basePart.HostType == Flags.IPv6HostType) {
-               if (basePart.IsImplicitFile) {
-                   left =  @"\\[" + basePart.DnsSafeHost + ']';
-               }
-               else {
-                   left =  basePart.GetParts(UriComponents.Scheme|UriComponents.UserInfo, uriFormat)
-                           + '[' + basePart.DnsSafeHost + ']'
-                           + basePart.GetParts(UriComponents.KeepDelimiter|UriComponents.Port, uriFormat);
-               }
-           }
-           else {
-               if (basePart.IsImplicitFile) {
-#if !PLATFORM_UNIX
-                   if (basePart.IsDosPath) {
-                       // The FILE DOS path comes as /c:/path, we have to exclude first 3 chars from compression
-                       path = Compress(path, 3, ref length, basePart.Syntax);
-                       return new string(path, 1, length-1) + extra;
-                   }
-                   else {
-                       left =  @"\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped);
-                   }
-#else
-                   left =  basePart.GetParts(UriComponents.Host, UriFormat.Unescaped);
-#endif // !PLATFORM_UNIX
-
-               }
-               else {
-                   left =  basePart.GetParts(UriComponents.SchemeAndServer|UriComponents.UserInfo, uriFormat);
-               }
-           }
-           //compress the path
-           path = Compress(path, basePart.SecuredPathIndex, ref length, basePart.Syntax);
-           return left + new string(path, 0, length) + extra;
-        }
-
-        //
-        // PathDifference
-        //
-        //  Performs the relative path calculation for MakeRelative()
-        //
-        // Inputs:
-        //  <argument>  path1
-        //  <argument>  path2
-        //      Paths for which we calculate the difference
-        //
-        //  <argument>  compareCase
-        //      False if we consider characters that differ only in case to be
-        //      equal
-        //
-        // Returns:
-        //  A string which is the relative path difference between <path1> and
-        //  <path2> such that if <path1> and the calculated difference are used
-        //  as arguments to Combine(), <path2> is returned
-        //
-        // Throws:
-        //  Nothing
-        //
-        private static string PathDifference(string path1, string path2, bool compareCase) {
-
-            int i;
-            int si = -1;
-
-            for (i = 0; (i < path1.Length) && (i < path2.Length); ++i) {
-                if ((path1[i] != path2[i]) 
-                    && (compareCase 
-                        || (Char.ToLower(path1[i], CultureInfo.InvariantCulture) 
-                            != Char.ToLower(path2[i], CultureInfo.InvariantCulture))))
-                {
-                    break;
-
-                } else if (path1[i] == '/') {
-                    si = i;
-                }
-            }
-
-            if (i == 0) {
-                return path2;
-            }
-            if ((i == path1.Length) && (i == path2.Length)) {
-                return String.Empty;
-            }
-
-            StringBuilder relPath = new StringBuilder();
-            // Walk down several dirs
-            for (; i < path1.Length; ++i) {
-                if (path1[i] == '/') {
-                    relPath.Append("../");
-                }
-            }
-            // Same path except that path1 ended with a file name and path2 didn't
-            if (relPath.Length == 0 && path2.Length - 1 == si)
-                return "./"; // Truncate the file name
-            return relPath.ToString() + path2.Substring(si + 1);
-        }
-
-        //Used by Uribuilder
-        internal bool HasAuthority {
-            get {
-                return InFact(Flags.AuthorityFound);
-            }
-        }
-
-        private static readonly char[] _WSchars = new char[] {' ', '\n', '\r', '\t'};
-        private static bool IsLWS(char ch) {
-
-            return (ch <= ' ') && (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t');
-        }
-
-        //Only consider ASCII characters
-        private static bool IsAsciiLetter(char character) {
-
-            return (character >= 'a' && character <= 'z') ||
-                   (character >= 'A' && character <= 'Z');
-        }
-
-        internal static bool IsAsciiLetterOrDigit(char character) {
-            return IsAsciiLetter(character) || (character >= '0' && character <= '9');
-        }
-        
-        //
-        // Is this a Bidirectional control char.. These get stripped
-        //
-        internal static bool IsBidiControlCharacter(char ch)
-        {
-            return (ch == '\u200E' /*LRM*/ || ch == '\u200F' /*RLM*/ || ch == '\u202A' /*LRE*/ ||
-                    ch == '\u202B' /*RLE*/ || ch == '\u202C' /*PDF*/ || ch == '\u202D' /*LRO*/ ||
-                    ch == '\u202E' /*RLO*/);
-        }
-
-        //
-        // Strip Bidirectional control charcters from this string
-        //
-        internal static unsafe string StripBidiControlCharacter(char* strToClean, int start, int length)
-        {
-            if (length <= 0) return "";
-
-            char [] cleanStr = new char[length];
-            int count = 0;
-            for (int i = 0; i < length; ++i){
-                char c = strToClean[start + i];
-                if (c < '\u200E' || c > '\u202E' || !IsBidiControlCharacter(c)){
-                    cleanStr[count++] = c;
-                }
-            }
-            return new string(cleanStr, 0, count);
-        }
-
-        //
-        // MakeRelative (toUri)
-        //
-        //  Return a relative path which when applied to this Uri would create the
-        //  resulting Uri <toUri>
-        //
-        // Inputs:
-        //  <argument>  toUri
-        //      Uri to which we calculate the transformation from this Uri
-        //
-        // Returns:
-        //  If the 2 Uri are common except for a relative path difference, then that
-        //  difference, else the display name of this Uri
-        //
-        // Throws:
-        //  ArgumentNullException, InvalidOperationException
-        //
-        [Obsolete("The method has been deprecated. Please use MakeRelativeUri(Uri uri). http://go.microsoft.com/fwlink/?linkid=14202")]
-        public string MakeRelative(Uri toUri)
-        {
-            if ((object)toUri == null)
-                throw new ArgumentNullException("toUri");
-
-            if (IsNotAbsoluteUri || toUri.IsNotAbsoluteUri)
-                throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-
-            if ((Scheme == toUri.Scheme) && (Host == toUri.Host) && (Port == toUri.Port))
-                return PathDifference(AbsolutePath, toUri.AbsolutePath, !IsUncOrDosPath);
-
-            return toUri.ToString();
-        }
-
-        /// <internalonly/>
-        [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected virtual void Parse()
-        {
-            // Microsoft cr: In V1-Everett this method if suppressed by the derived class
-            // would lead to an unconstructed Uri instance.
-            // It does not make any sense and violates Fxcop on calling a virtual method in the ctor.
-            // Should be deprecated and removed asap.
-        }
-        /// <internalonly/>
-        [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected virtual void Canonicalize()
-        {
-            // Microsoft cr: In V1-Everett this method if suppressed by the derived class
-            // would lead to supressing of a path compression
-            // It does not make much sense and violates Fxcop on calling a virtual method in the ctor.
-            // Should be deprecated and removed asap.
-        }
-        /// <internalonly/>
-        [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected virtual void Escape()
-        {
-            // Microsoft cr: In V1-Everett this method if suppressed by the derived class
-            // would lead to the same effect as dontEscape=true.
-            // It does not make much sense and violates Fxcop on calling a virtual method in the ctor.
-            // Should be deprecated and removed asap.
-        }
-        //
-        // Unescape
-        //
-        //  Convert any escape sequences in <path>. Escape sequences can be
-        //  hex encoded reserved characters (e.g. %40 == '@') or hex encoded
-        //  UTF-8 sequences (e.g. %C4%D2 == 'Latin capital Ligature Ij')
-        //
-        /// <internalonly/>
-        [Obsolete("The method has been deprecated. Please use GetComponents() or static UnescapeDataString() to unescape a Uri component or a string. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected virtual string Unescape(string path) {
-
-            // Microsoft cr: This method is dangerous since it gives path unescaping control
-            // to the derived class without any permission demand.
-            // Should be deprecated and removed asap.
-
-            char[] dest = new char[path.Length];
-            int count = 0;
-            dest = UriHelper.UnescapeString(path, 0, path.Length, dest, ref count, c_DummyChar, c_DummyChar, 
-                c_DummyChar, UnescapeMode.Unescape | UnescapeMode.UnescapeAll, null, false);
-            return new string(dest, 0, count);
-        }
-
-        [Obsolete("The method has been deprecated. Please use GetComponents() or static EscapeUriString() to escape a Uri component or a string. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected static string EscapeString(string str) {
-
-            // Microsoft cr: This method just does not make sense sa protected
-            // It should go public static asap
-
-            if ((object)str == null) {
-                return string.Empty;
-            }
-
-            int destStart = 0;
-            char[] dest = UriHelper.EscapeString(str, 0, str.Length, null, ref destStart, true, '?', '#', '%');
-            if ((object)dest == null)
-                return str;
-            return new string(dest, 0, destStart);
-        }
-
-        //
-        // CheckSecurity
-        //
-        //  Check for any invalid or problematic character sequences
-        //
-        /// <internalonly/>
-        [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected virtual void CheckSecurity()  {
-
-            // Microsoft cr: This method just does not make sense
-            // Should be deprecated and removed asap.
-
-            if (Scheme == "telnet") {
-
-                //
-                // remove everything after ';' for telnet
-                //
-
-            }
-        }
-
-        //
-        // IsReservedCharacter
-        //
-        //  Determine whether a character is part of the reserved set
-        //
-        // Returns:
-        //  true if <character> is reserved else false
-        //
-        /// <internalonly/>
-        [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected virtual bool IsReservedCharacter(char character) {
-
-            // Microsoft cr: This method just does not make sense as virtual protected
-            // It should go public static asap
-
-            return (character == ';')
-                || (character == '/')
-                || (character == ':')
-                || (character == '@')   // OK FS char
-                || (character == '&')
-                || (character == '=')
-                || (character == '+')   // OK FS char
-                || (character == '$')   // OK FS char
-                || (character == ',')
-                ;
-        }
-
-        //
-        // IsExcludedCharacter
-        //
-        //  Determine if a character should be exluded from a URI and therefore be
-        //  escaped
-        //
-        // Returns:
-        //  true if <character> should be escaped else false
-        //
-        /// <internalonly/>
-        [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected static bool IsExcludedCharacter(char character) {
-
-            // Microsoft cr: This method just does not make sense sa protected
-            // It should go public static asap
-
-            //
-            // the excluded characters...
-            //
-
-            return (character <= 0x20)
-                || (character >= 0x7f)
-                || (character == '<')
-                || (character == '>')
-                || (character == '#')
-                || (character == '%')
-                || (character == '"')
-
-                //
-                // the 'unwise' characters...
-                //
-
-                || (character == '{')
-                || (character == '}')
-                || (character == '|')
-                || (character == '\\')
-                || (character == '^')
-                || (character == '[')
-                || (character == ']')
-                || (character == '`')
-                ;
-        }
-
-        //
-        // IsBadFileSystemCharacter
-        //
-        //  Determine whether a character would be an invalid character if used in
-        //  a file system name. Note, this is really based on NTFS rules
-        //
-        // Returns:
-        //  true if <character> would be a treated as a bad file system character
-        //  else false
-        //
-        [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
-        protected virtual bool IsBadFileSystemCharacter(char character) {
-
-            // Microsoft cr: This method just does not make sense sa protected virtual
-            // It should go public static asap
-
-            return (character < 0x20)
-                || (character == ';')
-                || (character == '/')
-                || (character == '?')
-                || (character == ':')
-                || (character == '&')
-                || (character == '=')
-                || (character == ',')
-                || (character == '*')
-                || (character == '<')
-                || (character == '>')
-                || (character == '"')
-                || (character == '|')
-                || (character == '\\')
-                || (character == '^')
-                ;
-        }
-
-
-    } // class Uri
-} // namespace System
-
+// #endif // !PLATFORM_UNIX
+//
+//            // Check special case for Unc or absolute path in relativePart when base is FILE
+//            if (StaticIsFile(basePart.Syntax))
+//            {
+//
+//                 if (c1 == '\\' || c1 == '/') {
+//
+//                     if(relativePart.Length >= 2 && (relativePart[1] == '\\' || relativePart[1] == '/')) {
+//                         //Assuming relative is a Unc path and base is a file uri.
+//                         return basePart.IsImplicitFile? relativePart: "file:" + relativePart;
+//                     }
+//
+//                     // here we got an absolute path in relativePart,
+//                     // For compatibility with V1.0 parser we restrict the compression scope to Unc Share, i.e. \\host\share\
+//                     if (basePart.IsUnc) {
+//                         string share = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter, 
+//                             UriFormat.Unescaped);
+//                         for (int i = 1; i < share.Length; ++i) {
+//                             if (share[i] == '/') {
+//                                 share = share.Substring(0, i);
+//                                 break;
+//                             }
+//                         }
+//                         if (basePart.IsImplicitFile) {
+//                             return  @"\\"
+//                                     + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped)
+//                                     + share
+//                                     + relativePart;
+//                         }
+//                         return  "file://"
+//                                 + basePart.GetParts(UriComponents.Host, uriFormat)
+//                                 + share
+//                                 + relativePart;
+//
+//                     }
+//                     // It's not obvious but we've checked (for this relativePart format) that baseUti is nor UNC nor DOS path
+//                     //
+//                     // Means base is a Unix style path and, btw, IsImplicitFile cannot be the case either
+//                     return "file://" + relativePart;
+//                }
+//            }
+//
+//            // If we are here we did not recognize absolute DOS/UNC path for a file: base uri
+//            // Note that DOS path may still happen in the relativePart and if so it may override the base uri scheme.
+//
+//            bool convBackSlashes =  basePart.Syntax.InFact(UriSyntaxFlags.ConvertPathSlashes);
+//
+//            string left = null;
+//
+//            // check for network or local absolute path
+//            if (c1 == '/' || (c1 == '\\' && convBackSlashes)) {
+//                if (relativePart.Length >= 2 && relativePart[1] == '/') {
+//                    // got an authority in relative path and the base scheme is not file (checked)
+//                    return basePart.Scheme + ':' + relativePart;
+//                }
+//
+//                // Got absolute relative path, and the base is nor FILE nor a DOS path (checked at the method start)
+//                if (basePart.HostType == Flags.IPv6HostType) {
+//                    left =  basePart.GetParts(UriComponents.Scheme|UriComponents.UserInfo, uriFormat)
+//                                     + '[' + basePart.DnsSafeHost + ']'
+//                                     + basePart.GetParts(UriComponents.KeepDelimiter|UriComponents.Port, uriFormat);
+//                }
+//                else {
+//                    left =  basePart.GetParts(UriComponents.SchemeAndServer|UriComponents.UserInfo, uriFormat);
+//                }
+//                //VsWhidbey#241426
+//                if (convBackSlashes && c1 == '\\')
+//                    relativePart = '/' + relativePart.Substring(1);
+//
+//                return left + relativePart;
+//            }
+//
+//            // Here we got a relative path
+//            // Need to run path Compression because this is how relative Uri combining works
+//
+//            // Take the base part path up to and including the last slash
+//            left = basePart.GetParts(UriComponents.Path | UriComponents.KeepDelimiter, 
+//                basePart.IsImplicitFile ? UriFormat.Unescaped : uriFormat);
+//            int length = left.Length;
+//            char[] path = new char[length + relativePart.Length];
+//
+//            if (length > 0) {
+//                left.CopyTo(0, path, 0, length);
+//                while(length > 0) {
+//                    if (path[--length] == '/') {
+//                        ++length;
+//                        break;
+//                    }
+//                }
+//            }
+//
+//            //Append relative path to the result
+//            relativePart.CopyTo(0, path, length, relativePart.Length);
+//
+//            // Split relative on path and extra (for compression)
+//            c1 = basePart.Syntax.InFact(UriSyntaxFlags.MayHaveQuery)? '?': c_DummyChar;
+//
+//            // The  implcit file check is to avoid a fragment in the implicit file combined uri.
+//            // The behavior change request is tracked vis VsWhidbey#261387 ans that was approved through VsWhidbey#266417.
+//            char c2 = (!basePart.IsImplicitFile && basePart.Syntax.InFact(UriSyntaxFlags.MayHaveFragment)) ? '#' : 
+//                c_DummyChar;
+//            string extra = String.Empty;
+//
+//            // assuming c_DummyChar may not happen in an unicode uri string
+//            if (!(c1 == c_DummyChar && c2 == c_DummyChar)) {
+//                int i=0;
+//                for (;i < relativePart.Length; ++i) {
+//                    if (path[length + i] == c1 || path[length + i] == c2) {
+//                        break;
+//                    }
+//                }
+//                if (i == 0) {
+//                    extra = relativePart;
+//                }
+//                else if (i < relativePart.Length) {
+//                    extra = relativePart.Substring(i);
+//                }
+//                length += i;
+//            }
+//            else {
+//                length += relativePart.Length;
+//            }
+//
+//            // Take the base part up to the path
+//            if (basePart.HostType == Flags.IPv6HostType) {
+//                if (basePart.IsImplicitFile) {
+//                    left =  @"\\[" + basePart.DnsSafeHost + ']';
+//                }
+//                else {
+//                    left =  basePart.GetParts(UriComponents.Scheme|UriComponents.UserInfo, uriFormat)
+//                            + '[' + basePart.DnsSafeHost + ']'
+//                            + basePart.GetParts(UriComponents.KeepDelimiter|UriComponents.Port, uriFormat);
+//                }
+//            }
+//            else {
+//                if (basePart.IsImplicitFile) {
+// #if !PLATFORM_UNIX
+//                    if (basePart.IsDosPath) {
+//                        // The FILE DOS path comes as /c:/path, we have to exclude first 3 chars from compression
+//                        path = Compress(path, 3, ref length, basePart.Syntax);
+//                        return new string(path, 1, length-1) + extra;
+//                    }
+//                    else {
+//                        left =  @"\\" + basePart.GetParts(UriComponents.Host, UriFormat.Unescaped);
+//                    }
+// #else
+//                    left =  basePart.GetParts(UriComponents.Host, UriFormat.Unescaped);
+// #endif // !PLATFORM_UNIX
+//
+//                }
+//                else {
+//                    left =  basePart.GetParts(UriComponents.SchemeAndServer|UriComponents.UserInfo, uriFormat);
+//                }
+//            }
+//            //compress the path
+//            path = Compress(path, basePart.SecuredPathIndex, ref length, basePart.Syntax);
+//            return left + new string(path, 0, length) + extra;
+//         }
+//
+//         //
+//         // PathDifference
+//         //
+//         //  Performs the relative path calculation for MakeRelative()
+//         //
+//         // Inputs:
+//         //  <argument>  path1
+//         //  <argument>  path2
+//         //      Paths for which we calculate the difference
+//         //
+//         //  <argument>  compareCase
+//         //      False if we consider characters that differ only in case to be
+//         //      equal
+//         //
+//         // Returns:
+//         //  A string which is the relative path difference between <path1> and
+//         //  <path2> such that if <path1> and the calculated difference are used
+//         //  as arguments to Combine(), <path2> is returned
+//         //
+//         // Throws:
+//         //  Nothing
+//         //
+//         private static string PathDifference(string path1, string path2, bool compareCase) {
+//
+//             int i;
+//             int si = -1;
+//
+//             for (i = 0; (i < path1.Length) && (i < path2.Length); ++i) {
+//                 if ((path1[i] != path2[i]) 
+//                     && (compareCase 
+//                         || (Char.ToLower(path1[i], CultureInfo.InvariantCulture) 
+//                             != Char.ToLower(path2[i], CultureInfo.InvariantCulture))))
+//                 {
+//                     break;
+//
+//                 } else if (path1[i] == '/') {
+//                     si = i;
+//                 }
+//             }
+//
+//             if (i == 0) {
+//                 return path2;
+//             }
+//             if ((i == path1.Length) && (i == path2.Length)) {
+//                 return String.Empty;
+//             }
+//
+//             StringBuilder relPath = new StringBuilder();
+//             // Walk down several dirs
+//             for (; i < path1.Length; ++i) {
+//                 if (path1[i] == '/') {
+//                     relPath.Append("../");
+//                 }
+//             }
+//             // Same path except that path1 ended with a file name and path2 didn't
+//             if (relPath.Length == 0 && path2.Length - 1 == si)
+//                 return "./"; // Truncate the file name
+//             return relPath.ToString() + path2.Substring(si + 1);
+//         }
+//
+//         //Used by Uribuilder
+//         internal bool HasAuthority {
+//             get {
+//                 return InFact(Flags.AuthorityFound);
+//             }
+//         }
+//
+//         private static readonly char[] _WSchars = new char[] {' ', '\n', '\r', '\t'};
+//         private static bool IsLWS(char ch) {
+//
+//             return (ch <= ' ') && (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t');
+//         }
+//
+//         //Only consider ASCII characters
+//         private static bool IsAsciiLetter(char character) {
+//
+//             return (character >= 'a' && character <= 'z') ||
+//                    (character >= 'A' && character <= 'Z');
+//         }
+//
+//         internal static bool IsAsciiLetterOrDigit(char character) {
+//             return IsAsciiLetter(character) || (character >= '0' && character <= '9');
+//         }
+//         
+//         //
+//         // Is this a Bidirectional control char.. These get stripped
+//         //
+//         internal static bool IsBidiControlCharacter(char ch)
+//         {
+//             return (ch == '\u200E' /*LRM*/ || ch == '\u200F' /*RLM*/ || ch == '\u202A' /*LRE*/ ||
+//                     ch == '\u202B' /*RLE*/ || ch == '\u202C' /*PDF*/ || ch == '\u202D' /*LRO*/ ||
+//                     ch == '\u202E' /*RLO*/);
+//         }
+//
+//         //
+//         // Strip Bidirectional control charcters from this string
+//         //
+//         internal static unsafe string StripBidiControlCharacter(char* strToClean, int start, int length)
+//         {
+//             if (length <= 0) return "";
+//
+//             char [] cleanStr = new char[length];
+//             int count = 0;
+//             for (int i = 0; i < length; ++i){
+//                 char c = strToClean[start + i];
+//                 if (c < '\u200E' || c > '\u202E' || !IsBidiControlCharacter(c)){
+//                     cleanStr[count++] = c;
+//                 }
+//             }
+//             return new string(cleanStr, 0, count);
+//         }
+//
+//         //
+//         // MakeRelative (toUri)
+//         //
+//         //  Return a relative path which when applied to this Uri would create the
+//         //  resulting Uri <toUri>
+//         //
+//         // Inputs:
+//         //  <argument>  toUri
+//         //      Uri to which we calculate the transformation from this Uri
+//         //
+//         // Returns:
+//         //  If the 2 Uri are common except for a relative path difference, then that
+//         //  difference, else the display name of this Uri
+//         //
+//         // Throws:
+//         //  ArgumentNullException, InvalidOperationException
+//         //
+//         [Obsolete("The method has been deprecated. Please use MakeRelativeUri(Uri uri). http://go.microsoft.com/fwlink/?linkid=14202")]
+//         public string MakeRelative(Uri toUri)
+//         {
+//             if ((object)toUri == null)
+//                 throw new ArgumentNullException("toUri");
+//
+//             if (IsNotAbsoluteUri || toUri.IsNotAbsoluteUri)
+//                 throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//
+//             if ((Scheme == toUri.Scheme) && (Host == toUri.Host) && (Port == toUri.Port))
+//                 return PathDifference(AbsolutePath, toUri.AbsolutePath, !IsUncOrDosPath);
+//
+//             return toUri.ToString();
+//         }
+//
+//         /// <internalonly/>
+//         [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected virtual void Parse()
+//         {
+//             // Microsoft cr: In V1-Everett this method if suppressed by the derived class
+//             // would lead to an unconstructed Uri instance.
+//             // It does not make any sense and violates Fxcop on calling a virtual method in the ctor.
+//             // Should be deprecated and removed asap.
+//         }
+//         /// <internalonly/>
+//         [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected virtual void Canonicalize()
+//         {
+//             // Microsoft cr: In V1-Everett this method if suppressed by the derived class
+//             // would lead to supressing of a path compression
+//             // It does not make much sense and violates Fxcop on calling a virtual method in the ctor.
+//             // Should be deprecated and removed asap.
+//         }
+//         /// <internalonly/>
+//         [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected virtual void Escape()
+//         {
+//             // Microsoft cr: In V1-Everett this method if suppressed by the derived class
+//             // would lead to the same effect as dontEscape=true.
+//             // It does not make much sense and violates Fxcop on calling a virtual method in the ctor.
+//             // Should be deprecated and removed asap.
+//         }
+//         //
+//         // Unescape
+//         //
+//         //  Convert any escape sequences in <path>. Escape sequences can be
+//         //  hex encoded reserved characters (e.g. %40 == '@') or hex encoded
+//         //  UTF-8 sequences (e.g. %C4%D2 == 'Latin capital Ligature Ij')
+//         //
+//         /// <internalonly/>
+//         [Obsolete("The method has been deprecated. Please use GetComponents() or static UnescapeDataString() to unescape a Uri component or a string. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected virtual string Unescape(string path) {
+//
+//             // Microsoft cr: This method is dangerous since it gives path unescaping control
+//             // to the derived class without any permission demand.
+//             // Should be deprecated and removed asap.
+//
+//             char[] dest = new char[path.Length];
+//             int count = 0;
+//             dest = UriHelper.UnescapeString(path, 0, path.Length, dest, ref count, c_DummyChar, c_DummyChar, 
+//                 c_DummyChar, UnescapeMode.Unescape | UnescapeMode.UnescapeAll, null, false);
+//             return new string(dest, 0, count);
+//         }
+//
+//         [Obsolete("The method has been deprecated. Please use GetComponents() or static EscapeUriString() to escape a Uri component or a string. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected static string EscapeString(string str) {
+//
+//             // Microsoft cr: This method just does not make sense sa protected
+//             // It should go public static asap
+//
+//             if ((object)str == null) {
+//                 return string.Empty;
+//             }
+//
+//             int destStart = 0;
+//             char[] dest = UriHelper.EscapeString(str, 0, str.Length, null, ref destStart, true, '?', '#', '%');
+//             if ((object)dest == null)
+//                 return str;
+//             return new string(dest, 0, destStart);
+//         }
+//
+//         //
+//         // CheckSecurity
+//         //
+//         //  Check for any invalid or problematic character sequences
+//         //
+//         /// <internalonly/>
+//         [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected virtual void CheckSecurity()  {
+//
+//             // Microsoft cr: This method just does not make sense
+//             // Should be deprecated and removed asap.
+//
+//             if (Scheme == "telnet") {
+//
+//                 //
+//                 // remove everything after ';' for telnet
+//                 //
+//
+//             }
+//         }
+//
+//         //
+//         // IsReservedCharacter
+//         //
+//         //  Determine whether a character is part of the reserved set
+//         //
+//         // Returns:
+//         //  true if <character> is reserved else false
+//         //
+//         /// <internalonly/>
+//         [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected virtual bool IsReservedCharacter(char character) {
+//
+//             // Microsoft cr: This method just does not make sense as virtual protected
+//             // It should go public static asap
+//
+//             return (character == ';')
+//                 || (character == '/')
+//                 || (character == ':')
+//                 || (character == '@')   // OK FS char
+//                 || (character == '&')
+//                 || (character == '=')
+//                 || (character == '+')   // OK FS char
+//                 || (character == '$')   // OK FS char
+//                 || (character == ',')
+//                 ;
+//         }
+//
+//         //
+//         // IsExcludedCharacter
+//         //
+//         //  Determine if a character should be exluded from a URI and therefore be
+//         //  escaped
+//         //
+//         // Returns:
+//         //  true if <character> should be escaped else false
+//         //
+//         /// <internalonly/>
+//         [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected static bool IsExcludedCharacter(char character) {
+//
+//             // Microsoft cr: This method just does not make sense sa protected
+//             // It should go public static asap
+//
+//             //
+//             // the excluded characters...
+//             //
+//
+//             return (character <= 0x20)
+//                 || (character >= 0x7f)
+//                 || (character == '<')
+//                 || (character == '>')
+//                 || (character == '#')
+//                 || (character == '%')
+//                 || (character == '"')
+//
+//                 //
+//                 // the 'unwise' characters...
+//                 //
+//
+//                 || (character == '{')
+//                 || (character == '}')
+//                 || (character == '|')
+//                 || (character == '\\')
+//                 || (character == '^')
+//                 || (character == '[')
+//                 || (character == ']')
+//                 || (character == '`')
+//                 ;
+//         }
+//
+//         //
+//         // IsBadFileSystemCharacter
+//         //
+//         //  Determine whether a character would be an invalid character if used in
+//         //  a file system name. Note, this is really based on NTFS rules
+//         //
+//         // Returns:
+//         //  true if <character> would be a treated as a bad file system character
+//         //  else false
+//         //
+//         [Obsolete("The method has been deprecated. It is not used by the system. http://go.microsoft.com/fwlink/?linkid=14202")]
+//         protected virtual bool IsBadFileSystemCharacter(char character) {
+//
+//             // Microsoft cr: This method just does not make sense sa protected virtual
+//             // It should go public static asap
+//
+//             return (character < 0x20)
+//                 || (character == ';')
+//                 || (character == '/')
+//                 || (character == '?')
+//                 || (character == ':')
+//                 || (character == '&')
+//                 || (character == '=')
+//                 || (character == ',')
+//                 || (character == '*')
+//                 || (character == '<')
+//                 || (character == '>')
+//                 || (character == '"')
+//                 || (character == '|')
+//                 || (character == '\\')
+//                 || (character == '^')
+//                 ;
+//         }
+//
+//
+//     } // class Uri
+// } // namespace System
+//
diff --git a/System/net/System/UriExt.cs b/System/net/System/UriExt.cs
index b9e018e..2e37717 100644
--- a/System/net/System/UriExt.cs
+++ b/System/net/System/UriExt.cs
@@ -1,1033 +1,1033 @@
-/*++
-Copyright (c) 2003 Microsoft Corporation
-
-Module Name:
-
-    UriExt.cs
-
-Abstract:
-
-    Uri extensibility model Implementation.
-    This file utilizes partial class feature.
-    Uri.cs file contains core System.Uri functionality.
-
-Author:
-    Alexei Vopilov    Nov 21 2003
-
-Revision History:
-
---*/
-
-namespace System {
-    using System.Globalization;
-    using System.Net;
-    using System.Text;
-    using System.Runtime.InteropServices;
-    using System.Diagnostics;
-
-    public partial class Uri {
-        //
-        // All public ctors go through here
-        //
-        private void CreateThis(string uri, bool dontEscape, UriKind uriKind)
-        {
-            // if (!Enum.IsDefined(typeof(UriKind), uriKind)) -- We currently believe that Enum.IsDefined() is too slow 
-            // to be used here.
-            if ((int)uriKind < (int)UriKind.RelativeOrAbsolute || (int)uriKind > (int)UriKind.Relative) {
-                throw new ArgumentException(SR.GetString(SR.net_uri_InvalidUriKind, uriKind));
-            }
-
-            m_String = uri == null? string.Empty: uri;
-
-            if (dontEscape)
-                m_Flags |= Flags.UserEscaped;
-
-            ParsingError err = ParseScheme(m_String, ref m_Flags, ref m_Syntax);
-            UriFormatException e;
-
-            InitializeUri(err, uriKind, out e);
-            if (e != null)
-                throw e;
-        }
-        //
-        private void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatException e)
-        {
-            if (err == ParsingError.None)
-            {
-                if (IsImplicitFile)
-                {
-                    // V1 compat VsWhidbey#252282
-                    // A relative Uri wins over implicit UNC path unless the UNC path is of the form "\\something" and 
-                    // uriKind != Absolute
-                    if (
-#if !PLATFORM_UNIX
-                        NotAny(Flags.DosPath) &&
-#endif // !PLATFORM_UNIX
-                        uriKind != UriKind.Absolute &&
-                       (uriKind == UriKind.Relative || (m_String.Length >= 2 && (m_String[0] != '\\' || m_String[1] != '\\'))))
-
-                    {
-                        m_Syntax = null; //make it be relative Uri
-                        m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
-                        e = null;
-                        return;
-                        // Otheriwse an absolute file Uri wins when it's of the form "\\something"
-                    }
-                    //
-                    // VsWhidbey#423805 and V1 compat issue
-                    // We should support relative Uris of the form c:\bla or c:/bla
-                    //
-#if !PLATFORM_UNIX
-                    else if (uriKind == UriKind.Relative && InFact(Flags.DosPath))
-                    {
-                        m_Syntax = null; //make it be relative Uri
-                        m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
-                        e = null;
-                        return;
-                        // Otheriwse an absolute file Uri wins when it's of the form "c:\something"
-                    }
-#endif // !PLATFORM_UNIX
-                }
-            }
-            else if (err > ParsingError.LastRelativeUriOkErrIndex)
-            {
-                //This is a fatal error based solely on scheme name parsing
-                m_String = null; // make it be invalid Uri
-                e = GetException(err);
-                return;
-            }
-
-            //
-            //
-            //
-            bool hasUnicode = false;
-
-            // Is there unicode ..
-            if ((!s_ConfigInitialized) && CheckForConfigLoad(m_String)){
-                InitializeUriConfig();
-            }
-
-            m_iriParsing = (s_IriParsing && ((m_Syntax == null) || m_Syntax.InFact(UriSyntaxFlags.AllowIriParsing)));
-            
-            if (m_iriParsing && 
-                (CheckForUnicode(m_String) || CheckForEscapedUnreserved(m_String))) {
-                m_Flags |= Flags.HasUnicode;
-                hasUnicode = true;
-                // switch internal strings
-                m_originalUnicodeString = m_String; // original string location changed
-            }
-
-            if (m_Syntax != null)
-            {
-                if (m_Syntax.IsSimple)
-                {
-                    if ((err = PrivateParseMinimal()) != ParsingError.None)
-                    {
-                        if (uriKind != UriKind.Absolute && err <= ParsingError.LastRelativeUriOkErrIndex)
-                        {
-                            // RFC 3986 Section 5.4.2 - http:(relativeUri) may be considered a valid relative Uri.
-                            m_Syntax = null; // convert to relative uri
-                            e = null;
-                            m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
-                        }
-                        else
-                            e = GetException(err);
-                    }
-                    else if (uriKind == UriKind.Relative)
-                    {
-                        // Here we know that we can create an absolute Uri, but the user has requested only a relative one
-                        e = GetException(ParsingError.CannotCreateRelative);
-                    }
-                    else
-                        e = null;
-                    // will return from here
-
-                    // Parse unicode and reserved characters only if we're sure that we have an absolute Uri, either because it was
-                    // specified via uriKind, or because the parsing error does not indicate that we have a relative URI.
-                    if (m_iriParsing && hasUnicode && (uriKind == UriKind.Absolute || err == ParsingError.None))
-                    {
-                        // In this scenario we need to parse the whole string 
-                        try
-                        {
-                            EnsureParseRemaining();
-                        }
-                        catch (UriFormatException ex)
-                        {
-                            if (ServicePointManager.AllowAllUriEncodingExpansion)
-                            {
-                                throw;
-                            }
-                            else
-                            {
-                                e = ex;
-                                return;
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    // offer custom parser to create a parsing context
-                    m_Syntax = m_Syntax.InternalOnNewUri();
-
-                    // incase they won't call us
-                    m_Flags |= Flags.UserDrivenParsing;
-
-                    // Ask a registered type to validate this uri
-                    m_Syntax.InternalValidate(this, out e);
-
-                    if (e != null)
-                    {
-                        // Can we still take it as a relative Uri?
-                        if (uriKind != UriKind.Absolute && err != ParsingError.None 
-                            && err <= ParsingError.LastRelativeUriOkErrIndex)
-                        {
-                            m_Syntax = null; // convert it to relative
-                            e = null;
-                            m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
-                        }
-                    }
-                    else // e == null
-                    {
-                        if (err != ParsingError.None || InFact(Flags.ErrorOrParsingRecursion))
-                        {
-                            // User parser took over on an invalid Uri
-                            SetUserDrivenParsing();
-                        }
-                        else if (uriKind == UriKind.Relative)
-                        {
-                            // Here we know that custom parser can create an absolute Uri, but the user has requested only a 
-                            // relative one
-                            e = GetException(ParsingError.CannotCreateRelative);
-                        }
-
-                        if (m_iriParsing && hasUnicode){
-                            // In this scenario we need to parse the whole string 
-                            try
-                            {
-                                EnsureParseRemaining();
-                            }
-                            catch (UriFormatException ex)
-                            {
-                                if (ServicePointManager.AllowAllUriEncodingExpansion)
-                                {
-                                    throw;
-                                }
-                                else
-                                {
-                                    e = ex;
-                                    return;
-                                }
-                            }
-                        }
-                        
-                    }
-                    // will return from here
-                }
-            }
-            // If we encountered any parsing errors that indicate this may be a relative Uri, 
-            // and we'll allow relative Uri's, then create one.
-            else if (err != ParsingError.None && uriKind != UriKind.Absolute 
-                && err <= ParsingError.LastRelativeUriOkErrIndex)
-            {
-                e = null;
-                m_Flags &= (Flags.UserEscaped | Flags.HasUnicode); // the only flags that makes sense for a relative uri
-                if (m_iriParsing && hasUnicode)
-                {
-                    // Iri'ze and then normalize relative uris
-                    m_String = EscapeUnescapeIri(m_originalUnicodeString, 0, m_originalUnicodeString.Length,
-                                                (UriComponents)0);
-                    try
-                    {
-                        if (UriParser.ShouldUseLegacyV2Quirks)
-                            m_String = m_String.Normalize(NormalizationForm.FormC);
-                    }
-                    catch (ArgumentException)
-                    {
-                        e = GetException(ParsingError.BadFormat);
-                    }
-                }
-            }
-            else
-            {
-               m_String = null; // make it be invalid Uri
-               e = GetException(err);
-            }
-        }
-        
-        //
-        // Checks if there are any unicode or escaped chars or ace to determine whether to load
-        // config
-        //
-        private unsafe bool CheckForConfigLoad(String data)
-        {
-            bool initConfig = false;
-            int length = data.Length;
-
-            fixed (char* temp = data){
-                for (int i = 0; i < length; ++i){
-
-                    if ((temp[i] > '\x7f') || (temp[i] == '%') ||
-                        ((temp[i] == 'x') && ((i + 3) < length) && (temp[i + 1] == 'n') && (temp[i + 2] == '-') && (temp[i + 3] == '-')))
-                    {
-
-                        // Unicode or maybe ace 
-                        initConfig = true;
-                        break;
-                    }
-                }
-
-
-            }
-
-            return initConfig;
-        }
-
-        //
-        // Unescapes entire string and checks if it has unicode chars
-        //
-        private bool CheckForUnicode(String data)
-        {
-            bool hasUnicode = false;
-            char[] chars = new char[data.Length];
-            int count = 0;
-
-            chars = UriHelper.UnescapeString(data, 0, data.Length, chars, ref count, c_DummyChar, c_DummyChar, 
-                c_DummyChar, UnescapeMode.Unescape | UnescapeMode.UnescapeAll, null, false);
-
-            for (int i = 0; i < count; ++i){
-                if (chars[i] > '\x7f'){
-                    // Unicode 
-                    hasUnicode = true;
-                    break;
-                }
-            }
-            return hasUnicode;
-        }
-
-        // Does this string have any %6A sequences that are 3986 Unreserved characters?  These should be un-escaped.
-        private unsafe bool CheckForEscapedUnreserved(String data)
-        {
-            fixed (char* tempPtr = data)
-            {
-                for (int i = 0; i < data.Length - 2; ++i)
-                {
-                    if (tempPtr[i] == '%' && IsHexDigit(tempPtr[i + 1]) && IsHexDigit(tempPtr[i + 2])
-                        && tempPtr[i + 1] >= '0' && tempPtr[i + 1] <= '7') // max 0x7F
-                    {
-                        char ch = UriHelper.EscapedAscii(tempPtr[i + 1], tempPtr[i + 2]);
-                        if (ch != c_DummyChar && UriHelper.Is3986Unreserved(ch))
-                        {
-                            return true;
-                        }
-                    }
-                }
-            }
-            return false;
-        }
-        
-        //
-        //
-        //  Returns true if the string represents a valid argument to the Uri ctor
-        //  If uriKind != AbsoluteUri then certain parsing erros are ignored but Uri usage is limited
-        //
-        public static bool TryCreate(string uriString, UriKind uriKind, out Uri result)
-        {
-            if ((object)uriString == null)
-            {
-                result = null;
-                return false;
-            }
-            UriFormatException e = null;
-            result = CreateHelper(uriString, false, uriKind, ref e);
-            return (object) e == null && result != null;
-        }
-        //
-        public static bool TryCreate(Uri baseUri, string relativeUri, out Uri result)
-        {
-            Uri relativeLink;
-            if (TryCreate(relativeUri, UriKind.RelativeOrAbsolute, out relativeLink))
-            {
-                if (!relativeLink.IsAbsoluteUri)
-                    return TryCreate(baseUri, relativeLink, out result);
-
-                result = relativeLink;
-                return true;
-            }
-            result = null;
-            return false;
-        }
-        //
-        public static bool TryCreate(Uri baseUri, Uri relativeUri, out Uri result)
-        {
-            result = null;
-
-            //Consider: Work out the baseUri==null case
-            if ((object)baseUri == null || (object)relativeUri == null)
-                return false;
-
-            if (baseUri.IsNotAbsoluteUri)
-                return false;
-
-            UriFormatException e;
-            string newUriString = null;
-
-            bool dontEscape;
-            if (baseUri.Syntax.IsSimple)
-            {
-                dontEscape = relativeUri.UserEscaped;
-                result = ResolveHelper(baseUri, relativeUri, ref newUriString, ref dontEscape, out e);
-            }
-            else
-            {
-                dontEscape = false;
-                newUriString = baseUri.Syntax.InternalResolve(baseUri, relativeUri, out e);
-            }
-
-            if (e != null)
-                return false;
-
-            if ((object) result == null)
-                result = CreateHelper(newUriString, dontEscape, UriKind.Absolute, ref e);
-
-            return (object) e == null && result != null && result.IsAbsoluteUri;
-        }
-        //
-        //
-        public string GetComponents(UriComponents components, UriFormat format)
-        {
-            if (((components & UriComponents.SerializationInfoString) != 0) && components != UriComponents.SerializationInfoString)
-                throw new ArgumentOutOfRangeException("components", components, SR.GetString(SR.net_uri_NotJustSerialization));
-
-            if ((format & ~UriFormat.SafeUnescaped) != 0)
-                throw new ArgumentOutOfRangeException("format");
-
-            if (IsNotAbsoluteUri)
-            {
-                if (components == UriComponents.SerializationInfoString)
-                    return GetRelativeSerializationString(format);
-                else
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
-            }
-
-            if (Syntax.IsSimple)
-                return GetComponentsHelper(components, format);
-
-            return Syntax.InternalGetComponents(this, components, format);
-        }
-        //
-        //
-        // This is for languages that do not support == != operators overloading
-        //
-        // Note that Uri.Equals will get an optimized path but is limited to true/fasle result only
-        //
-        public static int Compare(Uri uri1, Uri uri2, UriComponents partsToCompare, UriFormat compareFormat, 
-            StringComparison comparisonType)
-        {
-
-            if ((object) uri1 == null)
-            {
-                if (uri2 == null)
-                    return 0; // Equal
-                return -1;    // null < non-null
-            }
-            if ((object) uri2 == null)
-                return 1;     // non-null > null
-
-            // a relative uri is always less than an absolute one
-            if (!uri1.IsAbsoluteUri || !uri2.IsAbsoluteUri)
-                return uri1.IsAbsoluteUri? 1: uri2.IsAbsoluteUri? -1: string.Compare(uri1.OriginalString, 
-                    uri2.OriginalString, comparisonType);
-
-            return string.Compare(
-                                    uri1.GetParts(partsToCompare, compareFormat),
-                                    uri2.GetParts(partsToCompare, compareFormat),
-                                    comparisonType
-                                  );
-        }
-        
-        public bool IsWellFormedOriginalString()
-        {
-            if (IsNotAbsoluteUri || Syntax.IsSimple)
-                return InternalIsWellFormedOriginalString();
-
-            return Syntax.InternalIsWellFormedOriginalString(this);
-        }
-
-        // Consider: (perf) Making it to not create a Uri internally
-        public static bool IsWellFormedUriString(string uriString, UriKind uriKind)
-        {
-            Uri result;
-
-            if (!Uri.TryCreate(uriString, uriKind, out result))
-                return false;
-
-            return result.IsWellFormedOriginalString();
-        }
-
-        //
-        // Internal stuff
-        //
-
-        // Returns false if OriginalString value
-        // (1) is not correctly escaped as per URI spec excluding intl UNC name case
-        // (2) or is an absolute Uri that represents implicit file Uri "c:\dir\file"
-        // (3) or is an absolute Uri that misses a slash before path "file://c:/dir/file"
-        // (4) or contains unescaped backslashes even if they will be treated
-        //     as forward slashes like http:\\host/path\file or file:\\\c:\path
-        //
-        internal unsafe bool InternalIsWellFormedOriginalString()
-        {
-            if (UserDrivenParsing)
-                throw new InvalidOperationException(SR.GetString(SR.net_uri_UserDrivenParsing, this.GetType().FullName));
-
-            fixed (char* str = m_String)
-            {
-                ushort idx = 0;
-                //
-                // For a relative Uri we only care about escaping and backslashes
-                //
-                if (!IsAbsoluteUri)
-                {
-                    // my:scheme/path?query is not well formed because the colon is ambiguous
-                    if (!UriParser.ShouldUseLegacyV2Quirks && CheckForColonInFirstPathSegment(m_String))
-                    {
-                        return false;
-                    }
-                    return (CheckCanonical(str, ref idx, (ushort)m_String.Length, c_EOL) 
-                            & (Check.BackslashInPath | Check.EscapedCanonical)) == Check.EscapedCanonical;
-                }
-
-                //
-                // (2) or is an absolute Uri that represents implicit file Uri "c:\dir\file"
-                //
-                if (IsImplicitFile)
-                    return false;
-
-                //This will get all the offsets, a Host name will be checked separatelly below
-                EnsureParseRemaining();
-
-                Flags nonCanonical = (m_Flags & (Flags.E_CannotDisplayCanonical | Flags.IriCanonical));
-                // User, Path, Query or Fragment may have some non escaped characters
-                if (((nonCanonical & Flags.E_CannotDisplayCanonical & (Flags.E_UserNotCanonical | Flags.E_PathNotCanonical |
-                                        Flags.E_QueryNotCanonical | Flags.E_FragmentNotCanonical)) != Flags.Zero) &&
-                    (!m_iriParsing || (m_iriParsing &&
-                    (((nonCanonical & Flags.E_UserNotCanonical) == 0) || ((nonCanonical & Flags.UserIriCanonical) == 0)) &&
-                    (((nonCanonical & Flags.E_PathNotCanonical) == 0) || ((nonCanonical & Flags.PathIriCanonical) == 0)) &&
-                    (((nonCanonical & Flags.E_QueryNotCanonical) == 0) || ((nonCanonical & Flags.QueryIriCanonical) == 0)) &&
-                    (((nonCanonical & Flags.E_FragmentNotCanonical) == 0) || ((nonCanonical & Flags.FragmentIriCanonical) == 0)))))
-                {
-                    return false;
-                }
-
-                // checking on scheme:\\ or file:////
-                if (InFact(Flags.AuthorityFound))
-                {
-                    idx = (ushort)(m_Info.Offset.Scheme + m_Syntax.SchemeName.Length + 2);
-                    if (idx >= m_Info.Offset.User || m_String[idx - 1] == '\\' || m_String[idx] == '\\')
-                        return false;
-
-#if !PLATFORM_UNIX
-                    if (InFact(Flags.UncPath | Flags.DosPath))
-                    {
-                        while (++idx < m_Info.Offset.User && (m_String[idx] == '/' || m_String[idx] == '\\'))
-                            return false;
-                    }
-#endif // !PLATFORM_UNIX
-                }
-
-
-                // (3) or is an absolute Uri that misses a slash before path "file://c:/dir/file"
-                // Note that for this check to be more general we assert that if Path is non empty and if it requires a first slash
-                // (which looks absent) then the method has to fail.
-                // Today it's only possible for a Dos like path, i.e. file://c:/bla would fail below check.
-                if (InFact(Flags.FirstSlashAbsent) && m_Info.Offset.Query > m_Info.Offset.Path)
-                    return false;
-
-                // (4) or contains unescaped backslashes even if they will be treated
-                //     as forward slashes like http:\\host/path\file or file:\\\c:\path
-                // Note we do not check for Flags.ShouldBeCompressed i.e. allow // /./ and alike as valid
-                if (InFact(Flags.BackslashInPath))
-                    return false;
-
-                // Capturing a rare case like file:///c|/dir
-                if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] == '|')
-                    return false;
-
-                //
-                // May need some real CPU processing to anwser the request
-                //
-                //
-                // Check escaping for authority
-                //
-                // IPv6 hosts cannot be properly validated by CheckCannonical
-                if ((m_Flags & Flags.CanonicalDnsHost) == 0 && HostType != Flags.IPv6HostType)
-                {
-                    idx = m_Info.Offset.User;
-                    Check result = CheckCanonical(str, ref idx, (ushort)m_Info.Offset.Path, '/');
-                    if (((result & (Check.ReservedFound | Check.BackslashInPath | Check.EscapedCanonical)) 
-                        != Check.EscapedCanonical) 
-                        && (!m_iriParsing || (m_iriParsing 
-                            && ((result & (Check.DisplayCanonical | Check.FoundNonAscii | Check.NotIriCanonical))
-                                != (Check.DisplayCanonical | Check.FoundNonAscii)))))
-                    {
-                        return false;
-                    }
-                }
-
-                // Want to ensure there are slashes after the scheme
-                if ((m_Flags & (Flags.SchemeNotCanonical | Flags.AuthorityFound)) 
-                    == (Flags.SchemeNotCanonical | Flags.AuthorityFound))
-                {
-                    idx = (ushort)m_Syntax.SchemeName.Length;
-                    while (str[idx++] != ':') ;
-                    if (idx + 1 >= m_String.Length || str[idx] != '/' || str[idx + 1] != '/')
-                        return false;
-                }
-            }
-            //
-            // May be scheme, host, port or path need some canonicalization but still the uri string is found to be a 
-            // "well formed" one
-            //
-            return true;
-        }
-
-        //
-        //
-        //
-        public static string UnescapeDataString(string stringToUnescape)
-        {
-            if ((object) stringToUnescape == null)
-                throw new ArgumentNullException("stringToUnescape");
-
-            if (stringToUnescape.Length == 0)
-                return string.Empty;
-
-            unsafe {
-                fixed (char* pStr = stringToUnescape)
-                {
-                    int position;
-                    for (position = 0; position < stringToUnescape.Length; ++position)
-                        if (pStr[position] == '%')
-                            break;
-
-                    if (position == stringToUnescape.Length)
-                        return stringToUnescape;
-
-                    UnescapeMode unescapeMode = UnescapeMode.Unescape | UnescapeMode.UnescapeAll;                    
-                    position = 0;
-                    char[] dest = new char[stringToUnescape.Length];
-                    dest = UriHelper.UnescapeString(stringToUnescape, 0, stringToUnescape.Length, dest, ref position, 
-                        c_DummyChar, c_DummyChar, c_DummyChar, unescapeMode, null, false);
-                    return new string(dest, 0, position);
-                }
-            }
-        }
-        //
-        // Where stringToEscape is intented to be a completely unescaped URI string.
-        // This method will escape any character that is not a reserved or unreserved character, including percent signs.
-        // Note that EscapeUriString will also do not escape a '#' sign.
-        //
-        public static string EscapeUriString(string stringToEscape)
-        {
-            if ((object)stringToEscape == null)
-                throw new ArgumentNullException("stringToEscape");
-
-            if (stringToEscape.Length == 0)
-                return string.Empty;
-
-            int position = 0;
-            char[] dest = UriHelper.EscapeString(stringToEscape, 0, stringToEscape.Length, null, ref position, true, 
-                c_DummyChar, c_DummyChar, c_DummyChar);
-            if ((object) dest == null)
-                return stringToEscape;
-            return new string(dest, 0, position);
-        }
-        //
-        // Where stringToEscape is intended to be URI data, but not an entire URI.
-        // This method will escape any character that is not an unreserved character, including percent signs.
-        //
-        public static string EscapeDataString(string stringToEscape)
-        {
-            if ((object) stringToEscape == null)
-                throw new ArgumentNullException("stringToEscape");
-
-            if (stringToEscape.Length == 0)
-                return string.Empty;
-
-            int position = 0;
-            char[] dest = UriHelper.EscapeString(stringToEscape, 0, stringToEscape.Length, null, ref position, false, 
-                c_DummyChar, c_DummyChar, c_DummyChar);
-            if (dest == null)
-                return stringToEscape;
-            return new string(dest, 0, position);
-        }
-
-        //
-        // Cleans up the specified component according to Iri rules
-        // a) Chars allowed by iri in a component are unescaped if found escaped
-        // b) Bidi chars are stripped
-        //
-        // should be called only if IRI parsing is switched on 
-        internal unsafe string EscapeUnescapeIri(string input, int start, int end, UriComponents component)
-        {
-            fixed (char *pInput = input)
-            {
-                return IriHelper.EscapeUnescapeIri(pInput, start, end, component);
-            }
-        }
-        
-        // Should never be used except by the below method
-        private Uri(Flags flags, UriParser uriParser, string uri)
-        {
-            m_Flags = flags;
-            m_Syntax = uriParser;
-            m_String = uri;
-        }
-        //
-        // a Uri.TryCreate() method goes through here.
-        //
-        internal static Uri CreateHelper(string uriString, bool dontEscape, UriKind uriKind, ref UriFormatException e)
-        {
-            // if (!Enum.IsDefined(typeof(UriKind), uriKind)) -- We currently believe that Enum.IsDefined() is too slow 
-            // to be used here.
-            if ((int)uriKind < (int)UriKind.RelativeOrAbsolute || (int)uriKind > (int)UriKind.Relative){
-                throw new ArgumentException(SR.GetString(SR.net_uri_InvalidUriKind, uriKind));
-            }
-
-            UriParser syntax = null;
-            Flags flags = Flags.Zero;
-            ParsingError err = ParseScheme(uriString, ref flags, ref syntax);
-
-            if (dontEscape)
-                flags |= Flags.UserEscaped;
-
-            // We won't use User factory for these errors
-            if (err != ParsingError.None)
-            {
-                // If it looks as a relative Uri, custom factory is ignored
-                if (uriKind != UriKind.Absolute && err <= ParsingError.LastRelativeUriOkErrIndex)
-                    return new Uri((flags & Flags.UserEscaped), null, uriString);
-
-                return null;
-            }
-
-            // Cannot be relative Uri if came here
-            Uri result = new Uri(flags, syntax, uriString);
-
-            // Validate instance using ether built in or a user Parser
-            try
-            {
-                result.InitializeUri(err, uriKind, out e);
-
-                if (e == null)
-                    return result;
-
-                return null;
-            }
-            catch (UriFormatException ee)
-            {
-                Debug.Assert(!syntax.IsSimple, "A UriPraser threw on InitializeAndValidate.");
-                e = ee;
-                // A precaution since custom Parser should never throw in this case.
-                return null;
-            }
-        }
-        //
-        // Resolves into either baseUri or relativeUri according to conditions OR if not possible it uses newUriString 
-        // to  return combined URI strings from both Uris 
-        // otherwise if e != null on output the operation has failed
-        //
-
-        internal static Uri ResolveHelper(Uri baseUri, Uri relativeUri, ref string newUriString, ref bool userEscaped, 
-            out UriFormatException e)
-        {
-            Debug.Assert(!baseUri.IsNotAbsoluteUri && !baseUri.UserDrivenParsing, "Uri::ResolveHelper()|baseUri is not Absolute or is controlled by User Parser.");
-
-            e = null;
-            string relativeStr = string.Empty;
-
-            if ((object)relativeUri != null)
-            {
-                if (relativeUri.IsAbsoluteUri)
-                    return relativeUri;
-
-                relativeStr = relativeUri.OriginalString;
-                userEscaped = relativeUri.UserEscaped;
-            }
-            else
-                relativeStr = string.Empty;
-
-            // Here we can assert that passed "relativeUri" is indeed a relative one
-
-            if (relativeStr.Length > 0 && (IsLWS(relativeStr[0]) || IsLWS(relativeStr[relativeStr.Length - 1])))
-                relativeStr = relativeStr.Trim(_WSchars);
-
-            if (relativeStr.Length == 0)
-            {
-                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri, 
-                    baseUri.UserEscaped ? UriFormat.UriEscaped : UriFormat.SafeUnescaped);
-                return null;
-            }
-
-            // Check for a simple fragment in relative part
-            if (relativeStr[0] == '#' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveFragment))
-            {
-                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, 
-                    UriFormat.UriEscaped) + relativeStr;
-                return null;
-            }
-            
-            // Check for a simple query in relative part
-            if (relativeStr[0] == '?' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveQuery))
-            {
-                newUriString = baseUri.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Query & ~UriComponents.Fragment, 
-                    UriFormat.UriEscaped) + relativeStr;
-                return null;
-            }
-            
-            // Check on the DOS path in the relative Uri (a special case)
-            if (relativeStr.Length >= 3
-                && (relativeStr[1] == ':' || relativeStr[1] == '|')
-                && IsAsciiLetter(relativeStr[0])
-                && (relativeStr[2] == '\\' || relativeStr[2] == '/'))
-            {
-
-                if (baseUri.IsImplicitFile)
-                {
-                    // It could have file:/// prepended to the result but we want to keep it as *Implicit* File Uri
-                    newUriString = relativeStr;
-                    return null;
-                }
-                else if (baseUri.Syntax.InFact(UriSyntaxFlags.AllowDOSPath))
-                {
-                    // The scheme is not changed just the path gets replaced
-                    string prefix;
-                    if (baseUri.InFact(Flags.AuthorityFound))
-                        prefix = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":///" : "://";
-                    else
-                        prefix = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":/" : ":";
-
-                    newUriString = baseUri.Scheme + prefix + relativeStr;
-                    return null;
-                }
-                // If we are here then input like "http://host/path/" + "C:\x" will produce the result  http://host/path/c:/x
-            }
-
-
-            ParsingError err = GetCombinedString(baseUri, relativeStr, userEscaped, ref newUriString);
-
-            if (err != ParsingError.None)
-            {
-                e = GetException(err);
-                return null;
-            }
-
-            if ((object)newUriString == (object)baseUri.m_String)
-                return baseUri;
-
-            return null;
-        }
-
-        private unsafe string GetRelativeSerializationString(UriFormat format)
-        {
-            if (format == UriFormat.UriEscaped)
-            {
-                if (m_String.Length == 0)
-                    return string.Empty;
-                int position = 0;
-                char[] dest = UriHelper.EscapeString(m_String, 0, m_String.Length, null, ref position, true, 
-                    c_DummyChar, c_DummyChar, '%');
-                if ((object)dest == null)
-                    return m_String;
-                return new string(dest, 0, position);
-            }
-
-            else if (format == UriFormat.Unescaped)
-                return UnescapeDataString(m_String);
-
-            else if (format == UriFormat.SafeUnescaped)
-            {
-                if (m_String.Length == 0)
-                    return string.Empty;
-
-                char[] dest = new char[m_String.Length];
-                int position = 0;
-                dest = UriHelper.UnescapeString(m_String, 0, m_String.Length, dest, ref position, c_DummyChar, 
-                    c_DummyChar, c_DummyChar, UnescapeMode.EscapeUnescape, null, false);
-                return new string(dest, 0, position);
-            }
-            else
-                throw new ArgumentOutOfRangeException("format");
-
-        }
-
-        //
-        // UriParser helpers methods
-        //
-        internal string GetComponentsHelper(UriComponents uriComponents, UriFormat uriFormat)
-        {
-            if (uriComponents == UriComponents.Scheme)
-                return m_Syntax.SchemeName;
-
-            // A serialzation info is "almost" the same as AbsoluteUri except for IPv6 + ScopeID hostname case
-            if ((uriComponents & UriComponents.SerializationInfoString) != 0)
-                uriComponents |= UriComponents.AbsoluteUri;
-
-            //This will get all the offsets, HostString will be created below if needed
-            EnsureParseRemaining();
-
-            if ((uriComponents & UriComponents.NormalizedHost) != 0)
-            {
-                // Down the path we rely on Host to be ON for NormalizedHost
-                uriComponents |= UriComponents.Host;
-            }
-
-            //Check to see if we need the host/authotity string
-            if ((uriComponents & UriComponents.Host) != 0)
-                EnsureHostString(true);
-
-            //This, single Port request is always processed here
-            if (uriComponents == UriComponents.Port || uriComponents == UriComponents.StrongPort)
-            {
-                if (((m_Flags & Flags.NotDefaultPort) != 0) || (uriComponents == UriComponents.StrongPort 
-                    && m_Syntax.DefaultPort != UriParser.NoDefaultPort))
-                {
-                    // recreate string from the port value
-                    return m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
-                }
-                return string.Empty;
-            }
-
-            if ((uriComponents & UriComponents.StrongPort) != 0)
-            {
-                // Down the path we rely on Port to be ON for StrongPort
-                uriComponents |= UriComponents.Port;
-            }
-
-            //This request sometime is faster to process here
-            if (uriComponents == UriComponents.Host && (uriFormat == UriFormat.UriEscaped 
-                || (( m_Flags & (Flags.HostNotCanonical | Flags.E_HostNotCanonical)) == 0)))
-            {
-                EnsureHostString(false);
-                return m_Info.Host;
-            }
-
-            switch (uriFormat)
-            {
-                case UriFormat.UriEscaped:
-                    return GetEscapedParts(uriComponents);
-
-                case V1ToStringUnescape:
-                case UriFormat.SafeUnescaped:
-                case UriFormat.Unescaped:
-                    return GetUnescapedParts(uriComponents, uriFormat);
-
-                default:
-                    throw new ArgumentOutOfRangeException("uriFormat");
-            }
-        }
-        //
-        //
-        public bool IsBaseOf(Uri uri)
-        {
-            if ((object)uri == null)
-                throw new ArgumentNullException("uri");
-
-            if (!IsAbsoluteUri)
-                return false;
-
-            if (Syntax.IsSimple)
-                return IsBaseOfHelper(uri);
-
-            return Syntax.InternalIsBaseOf(this, uri);
-        }
-        //
-        //
-        //
-        internal bool IsBaseOfHelper(Uri uriLink)
-        {
-            //TO 
-            if (!IsAbsoluteUri || UserDrivenParsing)
-                return false;
-
-            if (!uriLink.IsAbsoluteUri)
-            {
-                //a relative uri could have quite tricky form, it's better to fix it now.
-                string newUriString = null;
-                UriFormatException e;
-                bool dontEscape = false;
-
-                uriLink = ResolveHelper(this, uriLink, ref newUriString, ref dontEscape, out e);
-                if (e != null)
-                    return false;
-
-                if ((object)uriLink == null)
-                    uriLink = CreateHelper(newUriString, dontEscape, UriKind.Absolute, ref e);
-
-                if (e != null)
-                    return false;
-            }
-
-            if (Syntax.SchemeName != uriLink.Syntax.SchemeName)
-                return false;
-
-            // Canonicalize and test for substring match up to the last path slash
-            string me = GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, UriFormat.SafeUnescaped);
-            string she = uriLink.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, UriFormat.SafeUnescaped);
-
-            unsafe
-            {
-                fixed (char* pMe = me)
-                {
-                    fixed (char* pShe = she)
-                    {
-                        return UriHelper.TestForSubPath(pMe, (ushort)me.Length, pShe, (ushort)she.Length, 
-                            IsUncOrDosPath || uriLink.IsUncOrDosPath);
-                    }
-                }
-            }
-        }
-        //
-        // Only a ctor time call
-        //
-        private void CreateThisFromUri(Uri otherUri)
-        {
-            // Clone the other guy but develop own UriInfo member
-            m_Info = null;
-
-            m_Flags = otherUri.m_Flags;
-            if (InFact(Flags.MinimalUriInfoSet))
-            {
-                m_Flags &= ~(Flags.MinimalUriInfoSet | Flags.AllUriInfoSet | Flags.IndexMask);
-                // Port / Path offset
-                int portIndex = otherUri.m_Info.Offset.Path;
-                if (InFact(Flags.NotDefaultPort))
-                {
-                    // Find the start of the port.  Account for non-canonical ports like :00123
-                    while (otherUri.m_String[portIndex] != ':' && portIndex > otherUri.m_Info.Offset.Host)
-                    {
-                        portIndex--;
-                    }
-                    if (otherUri.m_String[portIndex] != ':')
-                    {
-                        // Something wrong with the NotDefaultPort flag.  Reset to path index
-                        Debug.Assert(false, "Uri failed to locate custom port at index: " + portIndex);
-                        portIndex = otherUri.m_Info.Offset.Path;
-                    }
-                }
-                m_Flags |= (Flags)portIndex; // Port or path
-            }
-
-            m_Syntax = otherUri.m_Syntax;
-            m_String = otherUri.m_String;
-            m_iriParsing = otherUri.m_iriParsing;
-            if (otherUri.OriginalStringSwitched){
-                m_originalUnicodeString = otherUri.m_originalUnicodeString;
-            }
-            if (otherUri.AllowIdn && (otherUri.InFact(Flags.IdnHost) || otherUri.InFact(Flags.UnicodeHost))){
-                m_DnsSafeHost = otherUri.m_DnsSafeHost;
-            }
-        }
-    }
-}
+// /*++
+// Copyright (c) 2003 Microsoft Corporation
+//
+// Module Name:
+//
+//     UriExt.cs
+//
+// Abstract:
+//
+//     Uri extensibility model Implementation.
+//     This file utilizes partial class feature.
+//     Uri.cs file contains core System.Uri functionality.
+//
+// Author:
+//     Alexei Vopilov    Nov 21 2003
+//
+// Revision History:
+//
+// --*/
+//
+// namespace System {
+//     using System.Globalization;
+//     using System.Net;
+//     using System.Text;
+//     using System.Runtime.InteropServices;
+//     using System.Diagnostics;
+//
+//     public partial class Uri {
+//         //
+//         // All public ctors go through here
+//         //
+//         private void CreateThis(string uri, bool dontEscape, UriKind uriKind)
+//         {
+//             // if (!Enum.IsDefined(typeof(UriKind), uriKind)) -- We currently believe that Enum.IsDefined() is too slow 
+//             // to be used here.
+//             if ((int)uriKind < (int)UriKind.RelativeOrAbsolute || (int)uriKind > (int)UriKind.Relative) {
+//                 throw new ArgumentException(SR.GetString(SR.net_uri_InvalidUriKind, uriKind));
+//             }
+//
+//             m_String = uri == null? string.Empty: uri;
+//
+//             if (dontEscape)
+//                 m_Flags |= Flags.UserEscaped;
+//
+//             ParsingError err = ParseScheme(m_String, ref m_Flags, ref m_Syntax);
+//             UriFormatException e;
+//
+//             InitializeUri(err, uriKind, out e);
+//             if (e != null)
+//                 throw e;
+//         }
+//         //
+//         private void InitializeUri(ParsingError err, UriKind uriKind, out UriFormatException e)
+//         {
+//             if (err == ParsingError.None)
+//             {
+//                 if (IsImplicitFile)
+//                 {
+//                     // V1 compat VsWhidbey#252282
+//                     // A relative Uri wins over implicit UNC path unless the UNC path is of the form "\\something" and 
+//                     // uriKind != Absolute
+//                     if (
+// #if !PLATFORM_UNIX
+//                         NotAny(Flags.DosPath) &&
+// #endif // !PLATFORM_UNIX
+//                         uriKind != UriKind.Absolute &&
+//                        (uriKind == UriKind.Relative || (m_String.Length >= 2 && (m_String[0] != '\\' || m_String[1] != '\\'))))
+//
+//                     {
+//                         m_Syntax = null; //make it be relative Uri
+//                         m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
+//                         e = null;
+//                         return;
+//                         // Otheriwse an absolute file Uri wins when it's of the form "\\something"
+//                     }
+//                     //
+//                     // VsWhidbey#423805 and V1 compat issue
+//                     // We should support relative Uris of the form c:\bla or c:/bla
+//                     //
+// #if !PLATFORM_UNIX
+//                     else if (uriKind == UriKind.Relative && InFact(Flags.DosPath))
+//                     {
+//                         m_Syntax = null; //make it be relative Uri
+//                         m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
+//                         e = null;
+//                         return;
+//                         // Otheriwse an absolute file Uri wins when it's of the form "c:\something"
+//                     }
+// #endif // !PLATFORM_UNIX
+//                 }
+//             }
+//             else if (err > ParsingError.LastRelativeUriOkErrIndex)
+//             {
+//                 //This is a fatal error based solely on scheme name parsing
+//                 m_String = null; // make it be invalid Uri
+//                 e = GetException(err);
+//                 return;
+//             }
+//
+//             //
+//             //
+//             //
+//             bool hasUnicode = false;
+//
+//             // Is there unicode ..
+//             if ((!s_ConfigInitialized) && CheckForConfigLoad(m_String)){
+//                 InitializeUriConfig();
+//             }
+//
+//             m_iriParsing = (s_IriParsing && ((m_Syntax == null) || m_Syntax.InFact(UriSyntaxFlags.AllowIriParsing)));
+//             
+//             if (m_iriParsing && 
+//                 (CheckForUnicode(m_String) || CheckForEscapedUnreserved(m_String))) {
+//                 m_Flags |= Flags.HasUnicode;
+//                 hasUnicode = true;
+//                 // switch internal strings
+//                 m_originalUnicodeString = m_String; // original string location changed
+//             }
+//
+//             if (m_Syntax != null)
+//             {
+//                 if (m_Syntax.IsSimple)
+//                 {
+//                     if ((err = PrivateParseMinimal()) != ParsingError.None)
+//                     {
+//                         if (uriKind != UriKind.Absolute && err <= ParsingError.LastRelativeUriOkErrIndex)
+//                         {
+//                             // RFC 3986 Section 5.4.2 - http:(relativeUri) may be considered a valid relative Uri.
+//                             m_Syntax = null; // convert to relative uri
+//                             e = null;
+//                             m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
+//                         }
+//                         else
+//                             e = GetException(err);
+//                     }
+//                     else if (uriKind == UriKind.Relative)
+//                     {
+//                         // Here we know that we can create an absolute Uri, but the user has requested only a relative one
+//                         e = GetException(ParsingError.CannotCreateRelative);
+//                     }
+//                     else
+//                         e = null;
+//                     // will return from here
+//
+//                     // Parse unicode and reserved characters only if we're sure that we have an absolute Uri, either because it was
+//                     // specified via uriKind, or because the parsing error does not indicate that we have a relative URI.
+//                     if (m_iriParsing && hasUnicode && (uriKind == UriKind.Absolute || err == ParsingError.None))
+//                     {
+//                         // In this scenario we need to parse the whole string 
+//                         try
+//                         {
+//                             EnsureParseRemaining();
+//                         }
+//                         catch (UriFormatException ex)
+//                         {
+//                             if (ServicePointManager.AllowAllUriEncodingExpansion)
+//                             {
+//                                 throw;
+//                             }
+//                             else
+//                             {
+//                                 e = ex;
+//                                 return;
+//                             }
+//                         }
+//                     }
+//                 }
+//                 else
+//                 {
+//                     // offer custom parser to create a parsing context
+//                     m_Syntax = m_Syntax.InternalOnNewUri();
+//
+//                     // incase they won't call us
+//                     m_Flags |= Flags.UserDrivenParsing;
+//
+//                     // Ask a registered type to validate this uri
+//                     m_Syntax.InternalValidate(this, out e);
+//
+//                     if (e != null)
+//                     {
+//                         // Can we still take it as a relative Uri?
+//                         if (uriKind != UriKind.Absolute && err != ParsingError.None 
+//                             && err <= ParsingError.LastRelativeUriOkErrIndex)
+//                         {
+//                             m_Syntax = null; // convert it to relative
+//                             e = null;
+//                             m_Flags &= Flags.UserEscaped; // the only flag that makes sense for a relative uri
+//                         }
+//                     }
+//                     else // e == null
+//                     {
+//                         if (err != ParsingError.None || InFact(Flags.ErrorOrParsingRecursion))
+//                         {
+//                             // User parser took over on an invalid Uri
+//                             SetUserDrivenParsing();
+//                         }
+//                         else if (uriKind == UriKind.Relative)
+//                         {
+//                             // Here we know that custom parser can create an absolute Uri, but the user has requested only a 
+//                             // relative one
+//                             e = GetException(ParsingError.CannotCreateRelative);
+//                         }
+//
+//                         if (m_iriParsing && hasUnicode){
+//                             // In this scenario we need to parse the whole string 
+//                             try
+//                             {
+//                                 EnsureParseRemaining();
+//                             }
+//                             catch (UriFormatException ex)
+//                             {
+//                                 if (ServicePointManager.AllowAllUriEncodingExpansion)
+//                                 {
+//                                     throw;
+//                                 }
+//                                 else
+//                                 {
+//                                     e = ex;
+//                                     return;
+//                                 }
+//                             }
+//                         }
+//                         
+//                     }
+//                     // will return from here
+//                 }
+//             }
+//             // If we encountered any parsing errors that indicate this may be a relative Uri, 
+//             // and we'll allow relative Uri's, then create one.
+//             else if (err != ParsingError.None && uriKind != UriKind.Absolute 
+//                 && err <= ParsingError.LastRelativeUriOkErrIndex)
+//             {
+//                 e = null;
+//                 m_Flags &= (Flags.UserEscaped | Flags.HasUnicode); // the only flags that makes sense for a relative uri
+//                 if (m_iriParsing && hasUnicode)
+//                 {
+//                     // Iri'ze and then normalize relative uris
+//                     m_String = EscapeUnescapeIri(m_originalUnicodeString, 0, m_originalUnicodeString.Length,
+//                                                 (UriComponents)0);
+//                     try
+//                     {
+//                         if (UriParser.ShouldUseLegacyV2Quirks)
+//                             m_String = m_String.Normalize(NormalizationForm.FormC);
+//                     }
+//                     catch (ArgumentException)
+//                     {
+//                         e = GetException(ParsingError.BadFormat);
+//                     }
+//                 }
+//             }
+//             else
+//             {
+//                m_String = null; // make it be invalid Uri
+//                e = GetException(err);
+//             }
+//         }
+//         
+//         //
+//         // Checks if there are any unicode or escaped chars or ace to determine whether to load
+//         // config
+//         //
+//         private unsafe bool CheckForConfigLoad(String data)
+//         {
+//             bool initConfig = false;
+//             int length = data.Length;
+//
+//             fixed (char* temp = data){
+//                 for (int i = 0; i < length; ++i){
+//
+//                     if ((temp[i] > '\x7f') || (temp[i] == '%') ||
+//                         ((temp[i] == 'x') && ((i + 3) < length) && (temp[i + 1] == 'n') && (temp[i + 2] == '-') && (temp[i + 3] == '-')))
+//                     {
+//
+//                         // Unicode or maybe ace 
+//                         initConfig = true;
+//                         break;
+//                     }
+//                 }
+//
+//
+//             }
+//
+//             return initConfig;
+//         }
+//
+//         //
+//         // Unescapes entire string and checks if it has unicode chars
+//         //
+//         private bool CheckForUnicode(String data)
+//         {
+//             bool hasUnicode = false;
+//             char[] chars = new char[data.Length];
+//             int count = 0;
+//
+//             chars = UriHelper.UnescapeString(data, 0, data.Length, chars, ref count, c_DummyChar, c_DummyChar, 
+//                 c_DummyChar, UnescapeMode.Unescape | UnescapeMode.UnescapeAll, null, false);
+//
+//             for (int i = 0; i < count; ++i){
+//                 if (chars[i] > '\x7f'){
+//                     // Unicode 
+//                     hasUnicode = true;
+//                     break;
+//                 }
+//             }
+//             return hasUnicode;
+//         }
+//
+//         // Does this string have any %6A sequences that are 3986 Unreserved characters?  These should be un-escaped.
+//         private unsafe bool CheckForEscapedUnreserved(String data)
+//         {
+//             fixed (char* tempPtr = data)
+//             {
+//                 for (int i = 0; i < data.Length - 2; ++i)
+//                 {
+//                     if (tempPtr[i] == '%' && IsHexDigit(tempPtr[i + 1]) && IsHexDigit(tempPtr[i + 2])
+//                         && tempPtr[i + 1] >= '0' && tempPtr[i + 1] <= '7') // max 0x7F
+//                     {
+//                         char ch = UriHelper.EscapedAscii(tempPtr[i + 1], tempPtr[i + 2]);
+//                         if (ch != c_DummyChar && UriHelper.Is3986Unreserved(ch))
+//                         {
+//                             return true;
+//                         }
+//                     }
+//                 }
+//             }
+//             return false;
+//         }
+//         
+//         //
+//         //
+//         //  Returns true if the string represents a valid argument to the Uri ctor
+//         //  If uriKind != AbsoluteUri then certain parsing erros are ignored but Uri usage is limited
+//         //
+//         public static bool TryCreate(string uriString, UriKind uriKind, out Uri result)
+//         {
+//             if ((object)uriString == null)
+//             {
+//                 result = null;
+//                 return false;
+//             }
+//             UriFormatException e = null;
+//             result = CreateHelper(uriString, false, uriKind, ref e);
+//             return (object) e == null && result != null;
+//         }
+//         //
+//         public static bool TryCreate(Uri baseUri, string relativeUri, out Uri result)
+//         {
+//             Uri relativeLink;
+//             if (TryCreate(relativeUri, UriKind.RelativeOrAbsolute, out relativeLink))
+//             {
+//                 if (!relativeLink.IsAbsoluteUri)
+//                     return TryCreate(baseUri, relativeLink, out result);
+//
+//                 result = relativeLink;
+//                 return true;
+//             }
+//             result = null;
+//             return false;
+//         }
+//         //
+//         public static bool TryCreate(Uri baseUri, Uri relativeUri, out Uri result)
+//         {
+//             result = null;
+//
+//             //Consider: Work out the baseUri==null case
+//             if ((object)baseUri == null || (object)relativeUri == null)
+//                 return false;
+//
+//             if (baseUri.IsNotAbsoluteUri)
+//                 return false;
+//
+//             UriFormatException e;
+//             string newUriString = null;
+//
+//             bool dontEscape;
+//             if (baseUri.Syntax.IsSimple)
+//             {
+//                 dontEscape = relativeUri.UserEscaped;
+//                 result = ResolveHelper(baseUri, relativeUri, ref newUriString, ref dontEscape, out e);
+//             }
+//             else
+//             {
+//                 dontEscape = false;
+//                 newUriString = baseUri.Syntax.InternalResolve(baseUri, relativeUri, out e);
+//             }
+//
+//             if (e != null)
+//                 return false;
+//
+//             if ((object) result == null)
+//                 result = CreateHelper(newUriString, dontEscape, UriKind.Absolute, ref e);
+//
+//             return (object) e == null && result != null && result.IsAbsoluteUri;
+//         }
+//         //
+//         //
+//         public string GetComponents(UriComponents components, UriFormat format)
+//         {
+//             if (((components & UriComponents.SerializationInfoString) != 0) && components != UriComponents.SerializationInfoString)
+//                 throw new ArgumentOutOfRangeException("components", components, SR.GetString(SR.net_uri_NotJustSerialization));
+//
+//             if ((format & ~UriFormat.SafeUnescaped) != 0)
+//                 throw new ArgumentOutOfRangeException("format");
+//
+//             if (IsNotAbsoluteUri)
+//             {
+//                 if (components == UriComponents.SerializationInfoString)
+//                     return GetRelativeSerializationString(format);
+//                 else
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_NotAbsolute));
+//             }
+//
+//             if (Syntax.IsSimple)
+//                 return GetComponentsHelper(components, format);
+//
+//             return Syntax.InternalGetComponents(this, components, format);
+//         }
+//         //
+//         //
+//         // This is for languages that do not support == != operators overloading
+//         //
+//         // Note that Uri.Equals will get an optimized path but is limited to true/fasle result only
+//         //
+//         public static int Compare(Uri uri1, Uri uri2, UriComponents partsToCompare, UriFormat compareFormat, 
+//             StringComparison comparisonType)
+//         {
+//
+//             if ((object) uri1 == null)
+//             {
+//                 if (uri2 == null)
+//                     return 0; // Equal
+//                 return -1;    // null < non-null
+//             }
+//             if ((object) uri2 == null)
+//                 return 1;     // non-null > null
+//
+//             // a relative uri is always less than an absolute one
+//             if (!uri1.IsAbsoluteUri || !uri2.IsAbsoluteUri)
+//                 return uri1.IsAbsoluteUri? 1: uri2.IsAbsoluteUri? -1: string.Compare(uri1.OriginalString, 
+//                     uri2.OriginalString, comparisonType);
+//
+//             return string.Compare(
+//                                     uri1.GetParts(partsToCompare, compareFormat),
+//                                     uri2.GetParts(partsToCompare, compareFormat),
+//                                     comparisonType
+//                                   );
+//         }
+//         
+//         public bool IsWellFormedOriginalString()
+//         {
+//             if (IsNotAbsoluteUri || Syntax.IsSimple)
+//                 return InternalIsWellFormedOriginalString();
+//
+//             return Syntax.InternalIsWellFormedOriginalString(this);
+//         }
+//
+//         // Consider: (perf) Making it to not create a Uri internally
+//         public static bool IsWellFormedUriString(string uriString, UriKind uriKind)
+//         {
+//             Uri result;
+//
+//             if (!Uri.TryCreate(uriString, uriKind, out result))
+//                 return false;
+//
+//             return result.IsWellFormedOriginalString();
+//         }
+//
+//         //
+//         // Internal stuff
+//         //
+//
+//         // Returns false if OriginalString value
+//         // (1) is not correctly escaped as per URI spec excluding intl UNC name case
+//         // (2) or is an absolute Uri that represents implicit file Uri "c:\dir\file"
+//         // (3) or is an absolute Uri that misses a slash before path "file://c:/dir/file"
+//         // (4) or contains unescaped backslashes even if they will be treated
+//         //     as forward slashes like http:\\host/path\file or file:\\\c:\path
+//         //
+//         internal unsafe bool InternalIsWellFormedOriginalString()
+//         {
+//             if (UserDrivenParsing)
+//                 throw new InvalidOperationException(SR.GetString(SR.net_uri_UserDrivenParsing, this.GetType().FullName));
+//
+//             fixed (char* str = m_String)
+//             {
+//                 ushort idx = 0;
+//                 //
+//                 // For a relative Uri we only care about escaping and backslashes
+//                 //
+//                 if (!IsAbsoluteUri)
+//                 {
+//                     // my:scheme/path?query is not well formed because the colon is ambiguous
+//                     if (!UriParser.ShouldUseLegacyV2Quirks && CheckForColonInFirstPathSegment(m_String))
+//                     {
+//                         return false;
+//                     }
+//                     return (CheckCanonical(str, ref idx, (ushort)m_String.Length, c_EOL) 
+//                             & (Check.BackslashInPath | Check.EscapedCanonical)) == Check.EscapedCanonical;
+//                 }
+//
+//                 //
+//                 // (2) or is an absolute Uri that represents implicit file Uri "c:\dir\file"
+//                 //
+//                 if (IsImplicitFile)
+//                     return false;
+//
+//                 //This will get all the offsets, a Host name will be checked separatelly below
+//                 EnsureParseRemaining();
+//
+//                 Flags nonCanonical = (m_Flags & (Flags.E_CannotDisplayCanonical | Flags.IriCanonical));
+//                 // User, Path, Query or Fragment may have some non escaped characters
+//                 if (((nonCanonical & Flags.E_CannotDisplayCanonical & (Flags.E_UserNotCanonical | Flags.E_PathNotCanonical |
+//                                         Flags.E_QueryNotCanonical | Flags.E_FragmentNotCanonical)) != Flags.Zero) &&
+//                     (!m_iriParsing || (m_iriParsing &&
+//                     (((nonCanonical & Flags.E_UserNotCanonical) == 0) || ((nonCanonical & Flags.UserIriCanonical) == 0)) &&
+//                     (((nonCanonical & Flags.E_PathNotCanonical) == 0) || ((nonCanonical & Flags.PathIriCanonical) == 0)) &&
+//                     (((nonCanonical & Flags.E_QueryNotCanonical) == 0) || ((nonCanonical & Flags.QueryIriCanonical) == 0)) &&
+//                     (((nonCanonical & Flags.E_FragmentNotCanonical) == 0) || ((nonCanonical & Flags.FragmentIriCanonical) == 0)))))
+//                 {
+//                     return false;
+//                 }
+//
+//                 // checking on scheme:\\ or file:////
+//                 if (InFact(Flags.AuthorityFound))
+//                 {
+//                     idx = (ushort)(m_Info.Offset.Scheme + m_Syntax.SchemeName.Length + 2);
+//                     if (idx >= m_Info.Offset.User || m_String[idx - 1] == '\\' || m_String[idx] == '\\')
+//                         return false;
+//
+// #if !PLATFORM_UNIX
+//                     if (InFact(Flags.UncPath | Flags.DosPath))
+//                     {
+//                         while (++idx < m_Info.Offset.User && (m_String[idx] == '/' || m_String[idx] == '\\'))
+//                             return false;
+//                     }
+// #endif // !PLATFORM_UNIX
+//                 }
+//
+//
+//                 // (3) or is an absolute Uri that misses a slash before path "file://c:/dir/file"
+//                 // Note that for this check to be more general we assert that if Path is non empty and if it requires a first slash
+//                 // (which looks absent) then the method has to fail.
+//                 // Today it's only possible for a Dos like path, i.e. file://c:/bla would fail below check.
+//                 if (InFact(Flags.FirstSlashAbsent) && m_Info.Offset.Query > m_Info.Offset.Path)
+//                     return false;
+//
+//                 // (4) or contains unescaped backslashes even if they will be treated
+//                 //     as forward slashes like http:\\host/path\file or file:\\\c:\path
+//                 // Note we do not check for Flags.ShouldBeCompressed i.e. allow // /./ and alike as valid
+//                 if (InFact(Flags.BackslashInPath))
+//                     return false;
+//
+//                 // Capturing a rare case like file:///c|/dir
+//                 if (IsDosPath && m_String[m_Info.Offset.Path + SecuredPathIndex - 1] == '|')
+//                     return false;
+//
+//                 //
+//                 // May need some real CPU processing to anwser the request
+//                 //
+//                 //
+//                 // Check escaping for authority
+//                 //
+//                 // IPv6 hosts cannot be properly validated by CheckCannonical
+//                 if ((m_Flags & Flags.CanonicalDnsHost) == 0 && HostType != Flags.IPv6HostType)
+//                 {
+//                     idx = m_Info.Offset.User;
+//                     Check result = CheckCanonical(str, ref idx, (ushort)m_Info.Offset.Path, '/');
+//                     if (((result & (Check.ReservedFound | Check.BackslashInPath | Check.EscapedCanonical)) 
+//                         != Check.EscapedCanonical) 
+//                         && (!m_iriParsing || (m_iriParsing 
+//                             && ((result & (Check.DisplayCanonical | Check.FoundNonAscii | Check.NotIriCanonical))
+//                                 != (Check.DisplayCanonical | Check.FoundNonAscii)))))
+//                     {
+//                         return false;
+//                     }
+//                 }
+//
+//                 // Want to ensure there are slashes after the scheme
+//                 if ((m_Flags & (Flags.SchemeNotCanonical | Flags.AuthorityFound)) 
+//                     == (Flags.SchemeNotCanonical | Flags.AuthorityFound))
+//                 {
+//                     idx = (ushort)m_Syntax.SchemeName.Length;
+//                     while (str[idx++] != ':') ;
+//                     if (idx + 1 >= m_String.Length || str[idx] != '/' || str[idx + 1] != '/')
+//                         return false;
+//                 }
+//             }
+//             //
+//             // May be scheme, host, port or path need some canonicalization but still the uri string is found to be a 
+//             // "well formed" one
+//             //
+//             return true;
+//         }
+//
+//         //
+//         //
+//         //
+//         public static string UnescapeDataString(string stringToUnescape)
+//         {
+//             if ((object) stringToUnescape == null)
+//                 throw new ArgumentNullException("stringToUnescape");
+//
+//             if (stringToUnescape.Length == 0)
+//                 return string.Empty;
+//
+//             unsafe {
+//                 fixed (char* pStr = stringToUnescape)
+//                 {
+//                     int position;
+//                     for (position = 0; position < stringToUnescape.Length; ++position)
+//                         if (pStr[position] == '%')
+//                             break;
+//
+//                     if (position == stringToUnescape.Length)
+//                         return stringToUnescape;
+//
+//                     UnescapeMode unescapeMode = UnescapeMode.Unescape | UnescapeMode.UnescapeAll;                    
+//                     position = 0;
+//                     char[] dest = new char[stringToUnescape.Length];
+//                     dest = UriHelper.UnescapeString(stringToUnescape, 0, stringToUnescape.Length, dest, ref position, 
+//                         c_DummyChar, c_DummyChar, c_DummyChar, unescapeMode, null, false);
+//                     return new string(dest, 0, position);
+//                 }
+//             }
+//         }
+//         //
+//         // Where stringToEscape is intented to be a completely unescaped URI string.
+//         // This method will escape any character that is not a reserved or unreserved character, including percent signs.
+//         // Note that EscapeUriString will also do not escape a '#' sign.
+//         //
+//         public static string EscapeUriString(string stringToEscape)
+//         {
+//             if ((object)stringToEscape == null)
+//                 throw new ArgumentNullException("stringToEscape");
+//
+//             if (stringToEscape.Length == 0)
+//                 return string.Empty;
+//
+//             int position = 0;
+//             char[] dest = UriHelper.EscapeString(stringToEscape, 0, stringToEscape.Length, null, ref position, true, 
+//                 c_DummyChar, c_DummyChar, c_DummyChar);
+//             if ((object) dest == null)
+//                 return stringToEscape;
+//             return new string(dest, 0, position);
+//         }
+//         //
+//         // Where stringToEscape is intended to be URI data, but not an entire URI.
+//         // This method will escape any character that is not an unreserved character, including percent signs.
+//         //
+//         public static string EscapeDataString(string stringToEscape)
+//         {
+//             if ((object) stringToEscape == null)
+//                 throw new ArgumentNullException("stringToEscape");
+//
+//             if (stringToEscape.Length == 0)
+//                 return string.Empty;
+//
+//             int position = 0;
+//             char[] dest = UriHelper.EscapeString(stringToEscape, 0, stringToEscape.Length, null, ref position, false, 
+//                 c_DummyChar, c_DummyChar, c_DummyChar);
+//             if (dest == null)
+//                 return stringToEscape;
+//             return new string(dest, 0, position);
+//         }
+//
+//         //
+//         // Cleans up the specified component according to Iri rules
+//         // a) Chars allowed by iri in a component are unescaped if found escaped
+//         // b) Bidi chars are stripped
+//         //
+//         // should be called only if IRI parsing is switched on 
+//         internal unsafe string EscapeUnescapeIri(string input, int start, int end, UriComponents component)
+//         {
+//             fixed (char *pInput = input)
+//             {
+//                 return IriHelper.EscapeUnescapeIri(pInput, start, end, component);
+//             }
+//         }
+//         
+//         // Should never be used except by the below method
+//         private Uri(Flags flags, UriParser uriParser, string uri)
+//         {
+//             m_Flags = flags;
+//             m_Syntax = uriParser;
+//             m_String = uri;
+//         }
+//         //
+//         // a Uri.TryCreate() method goes through here.
+//         //
+//         internal static Uri CreateHelper(string uriString, bool dontEscape, UriKind uriKind, ref UriFormatException e)
+//         {
+//             // if (!Enum.IsDefined(typeof(UriKind), uriKind)) -- We currently believe that Enum.IsDefined() is too slow 
+//             // to be used here.
+//             if ((int)uriKind < (int)UriKind.RelativeOrAbsolute || (int)uriKind > (int)UriKind.Relative){
+//                 throw new ArgumentException(SR.GetString(SR.net_uri_InvalidUriKind, uriKind));
+//             }
+//
+//             UriParser syntax = null;
+//             Flags flags = Flags.Zero;
+//             ParsingError err = ParseScheme(uriString, ref flags, ref syntax);
+//
+//             if (dontEscape)
+//                 flags |= Flags.UserEscaped;
+//
+//             // We won't use User factory for these errors
+//             if (err != ParsingError.None)
+//             {
+//                 // If it looks as a relative Uri, custom factory is ignored
+//                 if (uriKind != UriKind.Absolute && err <= ParsingError.LastRelativeUriOkErrIndex)
+//                     return new Uri((flags & Flags.UserEscaped), null, uriString);
+//
+//                 return null;
+//             }
+//
+//             // Cannot be relative Uri if came here
+//             Uri result = new Uri(flags, syntax, uriString);
+//
+//             // Validate instance using ether built in or a user Parser
+//             try
+//             {
+//                 result.InitializeUri(err, uriKind, out e);
+//
+//                 if (e == null)
+//                     return result;
+//
+//                 return null;
+//             }
+//             catch (UriFormatException ee)
+//             {
+//                 Debug.Assert(!syntax.IsSimple, "A UriPraser threw on InitializeAndValidate.");
+//                 e = ee;
+//                 // A precaution since custom Parser should never throw in this case.
+//                 return null;
+//             }
+//         }
+//         //
+//         // Resolves into either baseUri or relativeUri according to conditions OR if not possible it uses newUriString 
+//         // to  return combined URI strings from both Uris 
+//         // otherwise if e != null on output the operation has failed
+//         //
+//
+//         internal static Uri ResolveHelper(Uri baseUri, Uri relativeUri, ref string newUriString, ref bool userEscaped, 
+//             out UriFormatException e)
+//         {
+//             Debug.Assert(!baseUri.IsNotAbsoluteUri && !baseUri.UserDrivenParsing, "Uri::ResolveHelper()|baseUri is not Absolute or is controlled by User Parser.");
+//
+//             e = null;
+//             string relativeStr = string.Empty;
+//
+//             if ((object)relativeUri != null)
+//             {
+//                 if (relativeUri.IsAbsoluteUri)
+//                     return relativeUri;
+//
+//                 relativeStr = relativeUri.OriginalString;
+//                 userEscaped = relativeUri.UserEscaped;
+//             }
+//             else
+//                 relativeStr = string.Empty;
+//
+//             // Here we can assert that passed "relativeUri" is indeed a relative one
+//
+//             if (relativeStr.Length > 0 && (IsLWS(relativeStr[0]) || IsLWS(relativeStr[relativeStr.Length - 1])))
+//                 relativeStr = relativeStr.Trim(_WSchars);
+//
+//             if (relativeStr.Length == 0)
+//             {
+//                 newUriString = baseUri.GetParts(UriComponents.AbsoluteUri, 
+//                     baseUri.UserEscaped ? UriFormat.UriEscaped : UriFormat.SafeUnescaped);
+//                 return null;
+//             }
+//
+//             // Check for a simple fragment in relative part
+//             if (relativeStr[0] == '#' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveFragment))
+//             {
+//                 newUriString = baseUri.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, 
+//                     UriFormat.UriEscaped) + relativeStr;
+//                 return null;
+//             }
+//             
+//             // Check for a simple query in relative part
+//             if (relativeStr[0] == '?' && !baseUri.IsImplicitFile && baseUri.Syntax.InFact(UriSyntaxFlags.MayHaveQuery))
+//             {
+//                 newUriString = baseUri.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Query & ~UriComponents.Fragment, 
+//                     UriFormat.UriEscaped) + relativeStr;
+//                 return null;
+//             }
+//             
+//             // Check on the DOS path in the relative Uri (a special case)
+//             if (relativeStr.Length >= 3
+//                 && (relativeStr[1] == ':' || relativeStr[1] == '|')
+//                 && IsAsciiLetter(relativeStr[0])
+//                 && (relativeStr[2] == '\\' || relativeStr[2] == '/'))
+//             {
+//
+//                 if (baseUri.IsImplicitFile)
+//                 {
+//                     // It could have file:/// prepended to the result but we want to keep it as *Implicit* File Uri
+//                     newUriString = relativeStr;
+//                     return null;
+//                 }
+//                 else if (baseUri.Syntax.InFact(UriSyntaxFlags.AllowDOSPath))
+//                 {
+//                     // The scheme is not changed just the path gets replaced
+//                     string prefix;
+//                     if (baseUri.InFact(Flags.AuthorityFound))
+//                         prefix = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":///" : "://";
+//                     else
+//                         prefix = baseUri.Syntax.InFact(UriSyntaxFlags.PathIsRooted) ? ":/" : ":";
+//
+//                     newUriString = baseUri.Scheme + prefix + relativeStr;
+//                     return null;
+//                 }
+//                 // If we are here then input like "http://host/path/" + "C:\x" will produce the result  http://host/path/c:/x
+//             }
+//
+//
+//             ParsingError err = GetCombinedString(baseUri, relativeStr, userEscaped, ref newUriString);
+//
+//             if (err != ParsingError.None)
+//             {
+//                 e = GetException(err);
+//                 return null;
+//             }
+//
+//             if ((object)newUriString == (object)baseUri.m_String)
+//                 return baseUri;
+//
+//             return null;
+//         }
+//
+//         private unsafe string GetRelativeSerializationString(UriFormat format)
+//         {
+//             if (format == UriFormat.UriEscaped)
+//             {
+//                 if (m_String.Length == 0)
+//                     return string.Empty;
+//                 int position = 0;
+//                 char[] dest = UriHelper.EscapeString(m_String, 0, m_String.Length, null, ref position, true, 
+//                     c_DummyChar, c_DummyChar, '%');
+//                 if ((object)dest == null)
+//                     return m_String;
+//                 return new string(dest, 0, position);
+//             }
+//
+//             else if (format == UriFormat.Unescaped)
+//                 return UnescapeDataString(m_String);
+//
+//             else if (format == UriFormat.SafeUnescaped)
+//             {
+//                 if (m_String.Length == 0)
+//                     return string.Empty;
+//
+//                 char[] dest = new char[m_String.Length];
+//                 int position = 0;
+//                 dest = UriHelper.UnescapeString(m_String, 0, m_String.Length, dest, ref position, c_DummyChar, 
+//                     c_DummyChar, c_DummyChar, UnescapeMode.EscapeUnescape, null, false);
+//                 return new string(dest, 0, position);
+//             }
+//             else
+//                 throw new ArgumentOutOfRangeException("format");
+//
+//         }
+//
+//         //
+//         // UriParser helpers methods
+//         //
+//         internal string GetComponentsHelper(UriComponents uriComponents, UriFormat uriFormat)
+//         {
+//             if (uriComponents == UriComponents.Scheme)
+//                 return m_Syntax.SchemeName;
+//
+//             // A serialzation info is "almost" the same as AbsoluteUri except for IPv6 + ScopeID hostname case
+//             if ((uriComponents & UriComponents.SerializationInfoString) != 0)
+//                 uriComponents |= UriComponents.AbsoluteUri;
+//
+//             //This will get all the offsets, HostString will be created below if needed
+//             EnsureParseRemaining();
+//
+//             if ((uriComponents & UriComponents.NormalizedHost) != 0)
+//             {
+//                 // Down the path we rely on Host to be ON for NormalizedHost
+//                 uriComponents |= UriComponents.Host;
+//             }
+//
+//             //Check to see if we need the host/authotity string
+//             if ((uriComponents & UriComponents.Host) != 0)
+//                 EnsureHostString(true);
+//
+//             //This, single Port request is always processed here
+//             if (uriComponents == UriComponents.Port || uriComponents == UriComponents.StrongPort)
+//             {
+//                 if (((m_Flags & Flags.NotDefaultPort) != 0) || (uriComponents == UriComponents.StrongPort 
+//                     && m_Syntax.DefaultPort != UriParser.NoDefaultPort))
+//                 {
+//                     // recreate string from the port value
+//                     return m_Info.Offset.PortValue.ToString(CultureInfo.InvariantCulture);
+//                 }
+//                 return string.Empty;
+//             }
+//
+//             if ((uriComponents & UriComponents.StrongPort) != 0)
+//             {
+//                 // Down the path we rely on Port to be ON for StrongPort
+//                 uriComponents |= UriComponents.Port;
+//             }
+//
+//             //This request sometime is faster to process here
+//             if (uriComponents == UriComponents.Host && (uriFormat == UriFormat.UriEscaped 
+//                 || (( m_Flags & (Flags.HostNotCanonical | Flags.E_HostNotCanonical)) == 0)))
+//             {
+//                 EnsureHostString(false);
+//                 return m_Info.Host;
+//             }
+//
+//             switch (uriFormat)
+//             {
+//                 case UriFormat.UriEscaped:
+//                     return GetEscapedParts(uriComponents);
+//
+//                 case V1ToStringUnescape:
+//                 case UriFormat.SafeUnescaped:
+//                 case UriFormat.Unescaped:
+//                     return GetUnescapedParts(uriComponents, uriFormat);
+//
+//                 default:
+//                     throw new ArgumentOutOfRangeException("uriFormat");
+//             }
+//         }
+//         //
+//         //
+//         public bool IsBaseOf(Uri uri)
+//         {
+//             if ((object)uri == null)
+//                 throw new ArgumentNullException("uri");
+//
+//             if (!IsAbsoluteUri)
+//                 return false;
+//
+//             if (Syntax.IsSimple)
+//                 return IsBaseOfHelper(uri);
+//
+//             return Syntax.InternalIsBaseOf(this, uri);
+//         }
+//         //
+//         //
+//         //
+//         internal bool IsBaseOfHelper(Uri uriLink)
+//         {
+//             //TO 
+//             if (!IsAbsoluteUri || UserDrivenParsing)
+//                 return false;
+//
+//             if (!uriLink.IsAbsoluteUri)
+//             {
+//                 //a relative uri could have quite tricky form, it's better to fix it now.
+//                 string newUriString = null;
+//                 UriFormatException e;
+//                 bool dontEscape = false;
+//
+//                 uriLink = ResolveHelper(this, uriLink, ref newUriString, ref dontEscape, out e);
+//                 if (e != null)
+//                     return false;
+//
+//                 if ((object)uriLink == null)
+//                     uriLink = CreateHelper(newUriString, dontEscape, UriKind.Absolute, ref e);
+//
+//                 if (e != null)
+//                     return false;
+//             }
+//
+//             if (Syntax.SchemeName != uriLink.Syntax.SchemeName)
+//                 return false;
+//
+//             // Canonicalize and test for substring match up to the last path slash
+//             string me = GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, UriFormat.SafeUnescaped);
+//             string she = uriLink.GetParts(UriComponents.AbsoluteUri & ~UriComponents.Fragment, UriFormat.SafeUnescaped);
+//
+//             unsafe
+//             {
+//                 fixed (char* pMe = me)
+//                 {
+//                     fixed (char* pShe = she)
+//                     {
+//                         return UriHelper.TestForSubPath(pMe, (ushort)me.Length, pShe, (ushort)she.Length, 
+//                             IsUncOrDosPath || uriLink.IsUncOrDosPath);
+//                     }
+//                 }
+//             }
+//         }
+//         //
+//         // Only a ctor time call
+//         //
+//         private void CreateThisFromUri(Uri otherUri)
+//         {
+//             // Clone the other guy but develop own UriInfo member
+//             m_Info = null;
+//
+//             m_Flags = otherUri.m_Flags;
+//             if (InFact(Flags.MinimalUriInfoSet))
+//             {
+//                 m_Flags &= ~(Flags.MinimalUriInfoSet | Flags.AllUriInfoSet | Flags.IndexMask);
+//                 // Port / Path offset
+//                 int portIndex = otherUri.m_Info.Offset.Path;
+//                 if (InFact(Flags.NotDefaultPort))
+//                 {
+//                     // Find the start of the port.  Account for non-canonical ports like :00123
+//                     while (otherUri.m_String[portIndex] != ':' && portIndex > otherUri.m_Info.Offset.Host)
+//                     {
+//                         portIndex--;
+//                     }
+//                     if (otherUri.m_String[portIndex] != ':')
+//                     {
+//                         // Something wrong with the NotDefaultPort flag.  Reset to path index
+//                         Debug.Assert(false, "Uri failed to locate custom port at index: " + portIndex);
+//                         portIndex = otherUri.m_Info.Offset.Path;
+//                     }
+//                 }
+//                 m_Flags |= (Flags)portIndex; // Port or path
+//             }
+//
+//             m_Syntax = otherUri.m_Syntax;
+//             m_String = otherUri.m_String;
+//             m_iriParsing = otherUri.m_iriParsing;
+//             if (otherUri.OriginalStringSwitched){
+//                 m_originalUnicodeString = otherUri.m_originalUnicodeString;
+//             }
+//             if (otherUri.AllowIdn && (otherUri.InFact(Flags.IdnHost) || otherUri.InFact(Flags.UnicodeHost))){
+//                 m_DnsSafeHost = otherUri.m_DnsSafeHost;
+//             }
+//         }
+//     }
+// }
diff --git a/System/net/System/UriHelper.cs b/System/net/System/UriHelper.cs
index f81a765..a56645b 100644
--- a/System/net/System/UriHelper.cs
+++ b/System/net/System/UriHelper.cs
@@ -1,731 +1,731 @@
-namespace System 
-{
-    using System.Globalization;
-    using System.Text;
-    using System.Diagnostics;
-    
-    internal static class UriHelper
-    {
-        private static readonly char[] HexUpperChars = {
-                                   '0', '1', '2', '3', '4', '5', '6', '7',
-                                   '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-        
-        // http://host/Path/Path/File?Query is the base of
-        //      - http://host/Path/Path/File/ ...    (those "File" words may be different in semantic but anyway)
-        //      - http://host/Path/Path/#Fragment
-        //      - http://host/Path/Path/?Query
-        //      - http://host/Path/Path/MoreDir/ ...
-        //      - http://host/Path/Path/OtherFile?Query
-        //      - http://host/Path/Path/Fl
-        //      - http://host/Path/Path/
-        //
-        //  It is not a base for
-        //      - http://host/Path/Path         (that last "Path" is not considered as a directory)
-        //      - http://host/Path/Path?Query
-        //      - http://host/Path/Path#Fragment
-        //      - http://host/Path/Path2/
-        //      - http://host/Path/Path2/MoreDir
-        //      - http://host/Path/File
-        //
-        // ASSUMES that strings like http://host/Path/Path/MoreDir/../../  have been canonicalized before going to this method.
-        // ASSUMES that back slashes already have been converted if applicable.
-        //
-        internal static unsafe bool TestForSubPath(  char* pMe,  ushort meLength, char* pShe, ushort sheLength, 
-            bool ignoreCase) 
-        {
-            ushort i = 0;
-            char chMe;
-            char chShe;
-
-            bool AllSameBeforeSlash = true;
-
-            for( ;i < meLength && i < sheLength; ++i)
-            {
-                chMe  = *(pMe+i);
-                chShe = *(pShe+i);
-
-                if (chMe == '?' || chMe == '#') 
-                {
-                    // survived so far and pMe does not have any more path segments
-                    return true;
-                }
-
-                // If pMe terminates a path segment, so must pShe
-                if (chMe == '/') 
-                {
-                    if (chShe != '/') 
-                    {
-                        // comparison has falied
-                        return false;
-                    }
-                    // plus the segments must be the same
-                    if (!AllSameBeforeSlash) 
-                    {
-                        // comparison has falied
-                        return false;
-                    }
-                    //so far so good
-                    AllSameBeforeSlash = true;
-                    continue;
-                }
-
-                // if pShe terminates then pMe must not have any more path segments
-                if (chShe == '?' || chShe == '#') 
-                {
-                    break;
-                }
-
-                if (!ignoreCase) 
-                {
-                    if (chMe != chShe) 
-                    {
-                        AllSameBeforeSlash = false;
-                    }
-                }
-                else 
-                {
-                    if (Char.ToLower(chMe, CultureInfo.InvariantCulture) != Char.ToLower(chShe, CultureInfo.InvariantCulture)) 
-                    {
-                        AllSameBeforeSlash = false;
-                    }
-                }
-            }
-
-            // If me is longer then it must not have any more path segments
-            for (; i < meLength; ++i) 
-            {
-                if ((chMe = *(pMe+i)) == '?' || chMe == '#') 
-                {
-                    return true;
-                }
-                if (chMe == '/') 
-                {
-                    return false;
-                }
-            }
-            //survived by getting to the end of pMe
-            return true;
-        }
-
-        // - forceX characters are always escaped if found
-        // - rsvd character will remain unescaped
-        //
-        // start    - starting offset from input
-        // end      - the exclusive ending offset in input
-        // destPos  - starting offset in dest for output, on return this will be an exclusive "end" in the output.
-        //
-        // In case "dest" has lack of space it will be reallocated by preserving the _whole_ content up to current destPos
-        //
-        // Returns null if nothing has to be escaped AND passed dest was null, otherwise the resulting array with the updated destPos
-        //
-        const short c_MaxAsciiCharsReallocate   = 40;
-        const short c_MaxUnicodeCharsReallocate = 40;
-        const short c_MaxUTF_8BytesPerUnicodeChar  = 4;
-        const short c_EncodedCharsPerByte = 3;
-        internal unsafe static char[] EscapeString(string input, int start, int end, char[] dest, ref int destPos, 
-            bool isUriString, char force1, char force2, char rsvd)
-        {
-            if (end - start >= Uri.c_MaxUriBufferSize)
-                throw new UriFormatException(SR.GetString(SR.net_uri_SizeLimit));
-
-            int i = start;
-            int prevInputPos = start;
-            byte *bytes = stackalloc byte[c_MaxUnicodeCharsReallocate*c_MaxUTF_8BytesPerUnicodeChar];   // 40*4=160
-
-            fixed (char* pStr = input)
-            {
-                for(; i < end; ++i)
-                {
-                    char ch = pStr[i];
-
-                    // a Unicode ?
-                    if (ch  > '\x7F')
-                    {
-                        short maxSize = (short)Math.Min(end - i, (int)c_MaxUnicodeCharsReallocate-1);
-
-                        short count = 1;
-                        for (; count < maxSize && pStr[i + count] > '\x7f'; ++count)
-                            ;
-
-                        // Is the last a high surrogate?
-                        if (pStr[i + count-1] >= 0xD800 && pStr[i + count-1] <= 0xDBFF)
-                        {
-                            // Should be a rare case where the app tries to feed an invalid Unicode surrogates pair
-                           if (count == 1 || count == end - i)
-                                throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
-                           // need to grab one more char as a Surrogate except when it's a bogus input
-                           ++count;
-                        }
-
-                        dest = EnsureDestinationSize(pStr, dest, i, 
-                            (short)(count * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte), 
-                            c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte,
-                            ref destPos, prevInputPos);
-
-                        short numberOfBytes = (short)Encoding.UTF8.GetBytes(pStr+i, count, bytes, 
-                            c_MaxUnicodeCharsReallocate*c_MaxUTF_8BytesPerUnicodeChar);
-
-                        // This is the only exception that built in UriParser can throw after a Uri ctor.
-                        // Should not happen unless the app tries to feed an invalid Unicode String
-                        if (numberOfBytes == 0)
-                            throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
-
-                        i += (count-1);
-
-                        for (count = 0 ; count < numberOfBytes; ++count)
-                            EscapeAsciiChar((char)bytes[count], dest, ref destPos);
-
-                        prevInputPos = i+1;
-                    }
-                    else if (ch == '%' && rsvd == '%')
-                    {
-                        // Means we don't reEncode '%' but check for the possible escaped sequence
-                        dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte, 
-                            c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
-                        if(i + 2 < end && EscapedAscii(pStr[i+1], pStr[i+2]) != Uri.c_DummyChar)
-                        {
-                            // leave it escaped
-                            dest[destPos++] = '%';
-                            dest[destPos++] = pStr[i+1];
-                            dest[destPos++] = pStr[i+2];
-                            i += 2;
-                        }
-                        else
-                        {
-                            EscapeAsciiChar('%', dest, ref destPos);
-                        }
-                        prevInputPos = i+1;
-                    }
-                    else if (ch == force1 ||  ch == force2)
-                    {
-                        dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte, 
-                            c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
-                        EscapeAsciiChar(ch, dest, ref destPos);
-                        prevInputPos = i+1;
-                    }
-                    else if (ch != rsvd && (isUriString ? !IsReservedUnreservedOrHash(ch) : !IsUnreserved(ch)))
-                    {
-                        dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte, 
-                            c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
-                        EscapeAsciiChar(ch, dest, ref destPos);
-                        prevInputPos = i+1;
-                    }
-                }
-
-                if (prevInputPos != i)
-                {
-                    // need to fill up the dest array ?
-                    if (prevInputPos != start || dest != null)
-                        dest = EnsureDestinationSize(pStr, dest, i, 0, 0, ref destPos, prevInputPos);
-                }
-            }
-
-            return dest;
-        }
-
-        //
-        // ensure destination array has enough space and contains all the needed input stuff
-        //
-        private unsafe static char[] EnsureDestinationSize(char* pStr, char[] dest, int currentInputPos, 
-            short charsToAdd, short minReallocateChars, ref int destPos, int prevInputPos)
-        {
-            if ((object) dest == null || dest.Length  < destPos + (currentInputPos-prevInputPos) + charsToAdd)
-            {
-                // allocating or reallocating array by ensuring enough space based on maxCharsToAdd.
-                char[] newresult = new char[destPos + (currentInputPos-prevInputPos) + minReallocateChars];
-
-                if ((object) dest != null && destPos != 0)
-                    Buffer.BlockCopy(dest, 0, newresult, 0, destPos<<1);
-                dest = newresult;
-            }
-
-            // ensuring we copied everything form the input string left before last escaping
-            while (prevInputPos != currentInputPos)
-                dest[destPos++] = pStr[prevInputPos++];
-            return dest;
-        }
-        
-        //
-        // This method will assume that any good Escaped Sequence will be unescaped in the output
-        // - Assumes Dest.Length - detPosition >= end-start
-        // - UnescapeLevel controls various modes of opearion
-        // - Any "bad" escape sequence will remain as is or '%' will be escaped.
-        // - destPosition tells the starting index in dest for placing the result.
-        //   On return destPosition tells the last character + 1 postion in the "dest" array.
-        // - The control chars and chars passed in rsdvX parameters may be re-escaped depending on UnescapeLevel
-        // - It is a RARE case when Unescape actually needs escaping some characteres mentioned above.
-        //   For this reason it returns a char[] that is usually the same ref as the input "dest" value.
-        //
-        internal unsafe static char[] UnescapeString(string input, int start, int end, char[] dest, 
-            ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, 
-            bool isQuery)
-        {
-            fixed (char *pStr = input)
-            {
-                return UnescapeString(pStr, start, end, dest, ref destPosition, rsvd1, rsvd2, rsvd3, unescapeMode, 
-                    syntax, isQuery);
-            }
-        }
-        internal unsafe static char[] UnescapeString(char* pStr, int start, int end, char[] dest, ref int destPosition, 
-            char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery)
-        {
-            byte [] bytes = null;
-            byte escapedReallocations = 0;
-            bool escapeReserved = false;
-            int next = start;
-            bool iriParsing = Uri.IriParsingStatic(syntax)
-                                && ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.EscapeUnescape);
-            
-            while (true)
-            {
-                // we may need to re-pin dest[]
-                fixed (char* pDest = dest)
-                {
-                    if ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.CopyOnly)
-                    {
-                        while (start < end)
-                            pDest[destPosition++] = pStr[start++];
-                        return dest;
-                    }
-
-                    while (true)
-                    {
-                        char ch = (char)0;
-
-                        for (;next < end; ++next)
-                        {
-                            if ((ch = pStr[next]) == '%')
-                            {
-                                if ((unescapeMode & UnescapeMode.Unescape) == 0)
-                                {
-                                    // re-escape, don't check anything else
-                                    escapeReserved = true;
-                                }
-                                else if (next+2 < end)
-                                {
-                                    ch = EscapedAscii(pStr[next+1], pStr[next+2]);
-                                    // Unescape a good sequence if full unescape is requested
-                                    if (unescapeMode >= UnescapeMode.UnescapeAll)
-                                    {
-                                        if (ch == Uri.c_DummyChar)
-                                        {
-                                            if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
-                                            {
-                                                // Should be a rare case where the app tries to feed an invalid escaped sequence
-                                                throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
-                                            }
-                                            continue;
-                                        }
-                                    }
-                                    // re-escape % from an invalid sequence
-                                    else if (ch == Uri.c_DummyChar)
-                                    {
-                                        if ((unescapeMode & UnescapeMode.Escape) != 0)
-                                            escapeReserved = true;
-                                        else
-                                            continue;   // we should throw instead but since v1.0 would just print '%'
-                                    }
-                                    // Do not unescape '%' itself unless full unescape is requested
-                                    else if (ch == '%')
-                                    {
-                                        next += 2;
-                                        continue;
-                                    }
-                                    // Do not unescape a reserved char unless full unescape is requested
-                                    else if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
-                                    {
-                                        next += 2;
-                                        continue;
-                                    }
-                                    // Do not unescape a dangerous char unless it's V1ToStringFlags mode
-                                    else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 && IsNotSafeForUnescape(ch))
-                                    {
-                                        next += 2;
-                                        continue;
-                                    }
-                                    else if (iriParsing && ((ch <='\x9F' && IsNotSafeForUnescape(ch)) || 
-                                                            (ch >'\x9F' &&!IriHelper.CheckIriUnicodeRange(ch, isQuery))))
-                                    {
-                                        // check if unenscaping gives a char ouside iri range 
-                                        // if it does then keep it escaped
-                                        next += 2;
-                                        continue;
-                                    }
-                                    // unescape escaped char or escape %
-                                    break;
-                                }
-                                else if (unescapeMode >= UnescapeMode.UnescapeAll)
-                                {
-                                    if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
-                                    {
-                                        // Should be a rare case where the app tries to feed an invalid escaped sequence
-                                        throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
-                                    }
-                                    // keep a '%' as part of a bogus sequence 
-                                    continue;
-                                }
-                                else
-                                {
-                                    escapeReserved = true;
-                                }
-                                // escape (escapeReserved==ture) or otheriwse unescape the sequence
-                                break;
-                            }
-                            else if ((unescapeMode & (UnescapeMode.Unescape | UnescapeMode.UnescapeAll)) 
-                                == (UnescapeMode.Unescape | UnescapeMode.UnescapeAll))
-                            {
-                                continue;
-                            }
-                            else if ((unescapeMode & UnescapeMode.Escape) != 0)
-                            {
-                                 // Could actually escape some of the characters
-                                 if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
-                                 {
-                                     // found an unescaped reserved character -> escape it
-                                     escapeReserved = true;
-                                     break;
-                                 }
-                                 else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 
-                                     && (ch <= '\x1F' || (ch >= '\x7F' && ch <= '\x9F')))
-                                 {
-                                     // found an unescaped reserved character -> escape it
-                                     escapeReserved = true;
-                                     break;
-                                 }
-                            }
-                        }
-
-                        //copy off previous characters from input
-                        while (start < next)
-                            pDest[destPosition++] = pStr[start++];
-
-                        if (next != end)
-                        {
-                            //VsWhidbey#87423
-                            if (escapeReserved)
-                            {
-                                //escape that char
-                                // Since this should be _really_ rare case, reallocate with constant size increase of 30 rsvd-type characters.
-                                if (escapedReallocations == 0)
-                                {
-                                    escapedReallocations = 30;
-                                    char[] newDest = new char[dest.Length + escapedReallocations*3];
-                                    fixed (char *pNewDest = newDest)
-                                    {
-                                        for (int i = 0; i < destPosition; ++i)
-                                            pNewDest[i] = pDest[i];
-                                    }
-                                    dest = newDest;
-                                    // re-pin new dest[] array
-                                    goto dest_fixed_loop_break;
-                                }
-                                else
-                                {
-                                    --escapedReallocations;
-                                    EscapeAsciiChar(pStr[next], dest, ref destPosition);
-                                    escapeReserved = false;
-                                    start = ++next;
-                                    continue;
-                                }
-                            }
-
-                            // unescaping either one Ascii or possibly multiple Unicode
-
-                            if (ch <= '\x7F')
-                            {
-                                //ASCII
-                                dest[destPosition++] = ch;
-                                next+=3;
-                                start = next;
-                                continue;
-                            }
-
-                            // Unicode
-
-                            int byteCount = 1;
-                            // lazy initialization of max size, will reuse the array for next sequences
-                            if ((object) bytes == null)
-                                bytes = new byte[end - next];
-
-                            bytes[0] = (byte)ch;
-                            next+=3;
-                            while (next < end)
-                            {
-                                // Check on exit criterion
-                                if ((ch = pStr[next]) != '%' || next+2 >= end)
-                                    break;
-
-                                // already made sure we have 3 characters in str
-                                ch = EscapedAscii(pStr[next+1], pStr[next+2]);
-
-                                //invalid hex sequence ?
-                                if (ch == Uri.c_DummyChar)
-                                    break;
-                                // character is not part of a UTF-8 sequence ?
-                                else if (ch < '\x80')
-                                    break;
-                                else
-                                {
-                                    //a UTF-8 sequence
-                                    bytes[byteCount++] = (byte)ch;
-                                    next += 3;
-                                }
-                            }
-                            Encoding noFallbackCharUTF8 = (Encoding)Encoding.UTF8.Clone();
-                            noFallbackCharUTF8.EncoderFallback = new EncoderReplacementFallback("");
-                            noFallbackCharUTF8.DecoderFallback = new DecoderReplacementFallback("");
-
-                            char[] unescapedChars = new char[bytes.Length];
-                            int charCount = noFallbackCharUTF8.GetChars(bytes, 0, byteCount, unescapedChars, 0);
-
-                            start = next;
-
-                            // match exact bytes
-                            // Do not unescape chars not allowed by Iri
-                            // need to check for invalid utf sequences that may not have given any chars
-
-                            MatchUTF8Sequence(pDest, dest, ref destPosition, unescapedChars, charCount, bytes, 
-                                byteCount, isQuery, iriParsing);
-                        }
-
-                        if (next == end)
-                            goto done;
-                    }
-dest_fixed_loop_break: ;
-                }
-            }
-
-done:       return dest;
-        }
-
-        //
-        // Need to check for invalid utf sequences that may not have given any chars.
-        // We got the unescaped chars, we then reencode them and match off the bytes
-        // to get the invalid sequence bytes that we just copy off
-        //
-        internal static unsafe void MatchUTF8Sequence(char* pDest, char[] dest, ref int destOffset, char[] unescapedChars,
-            int charCount, byte[] bytes, int byteCount, bool isQuery, bool iriParsing)
-        {
-            int count = 0;
-            fixed (char* unescapedCharsPtr = unescapedChars)
-            {
-                for (int j = 0; j < charCount; ++j)
-                {
-                    bool isHighSurr = Char.IsHighSurrogate(unescapedCharsPtr[j]);
-
-                    byte[] encodedBytes = Encoding.UTF8.GetBytes(unescapedChars, j, isHighSurr ? 2 : 1);
-                    int encodedBytesLength = encodedBytes.Length;
-
-                    // we have to keep unicode chars outside Iri range escaped
-                    bool inIriRange = false;
-                    if (iriParsing) 
-                    {
-                        if (!isHighSurr)
-                            inIriRange = IriHelper.CheckIriUnicodeRange(unescapedChars[j], isQuery);
-                        else 
-                        {
-                            bool surrPair = false;
-                            inIriRange = IriHelper.CheckIriUnicodeRange(unescapedChars[j], unescapedChars[j + 1],
-                                                                   ref surrPair, isQuery);
-                        }
-                    }
-
-                    while (true)
-                    {
-                        // Escape any invalid bytes that were before this character
-                        while (bytes[count] != encodedBytes[0])
-                        {
-                            Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
-                            EscapeAsciiChar((char)bytes[count++], dest, ref destOffset);
-                        }
-
-                        // check if all bytes match
-                        bool allBytesMatch = true;
-                        int k = 0;
-                        for (; k < encodedBytesLength; ++k)
-                        {
-                            if (bytes[count + k] != encodedBytes[k])
-                            {
-                                allBytesMatch = false;
-                                break;
-                            }
-                        }
-
-                        if (allBytesMatch)
-                        {
-                            count += encodedBytesLength;
-                            if (iriParsing)
-                            {
-                                if (!inIriRange)
-                                {
-                                    // need to keep chars not allowed as escaped
-                                    for (int l = 0; l < encodedBytes.Length; ++l)
-                                    {
-                                        Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
-                                        EscapeAsciiChar((char)encodedBytes[l], dest, ref destOffset);
-                                    }
-                                }
-                                else if (!Uri.IsBidiControlCharacter(unescapedCharsPtr[j]) || !UriParser.DontKeepUnicodeBidiFormattingCharacters)
-                                {
-                                    //copy chars
-                                    Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
-                                    pDest[destOffset++] = unescapedCharsPtr[j];
-                                    if (isHighSurr)
-                                    {
-                                        Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
-                                        pDest[destOffset++] = unescapedCharsPtr[j + 1];
-                                    }
-                                }
-                            }
-                            else
-                            {
-                                //copy chars
-                                Debug.Assert(dest.Length > destOffset);
-                                pDest[destOffset++] = unescapedCharsPtr[j];
-
-                                if (isHighSurr)
-                                {
-                                    Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
-                                    pDest[destOffset++] = unescapedCharsPtr[j + 1];
-                                }
-                            }
-
-                            break; // break out of while (true) since we've matched this char bytes
-                        }
-                        else
-                        {
-                            // copy bytes till place where bytes dont match
-                            for (int l = 0; l < k; ++l)
-                            {
-                                Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
-                                EscapeAsciiChar((char)bytes[count++], dest, ref destOffset);
-                            }
-                        }
-                    }
-
-                    if (isHighSurr) j++;
-
-                }
-            }
-
-            // Include any trailing invalid sequences
-            while (count < byteCount) 
-            {
-                Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
-                EscapeAsciiChar((char)bytes[count++], dest, ref destOffset);
-            }
-        }
-
-        internal static void EscapeAsciiChar(char ch, char[] to, ref int pos)
-        {
-            to[pos++] = '%';
-            to[pos++] = HexUpperChars[(ch & 0xf0) >> 4];
-            to[pos++] = HexUpperChars[ch & 0xf];
-        }
-
-        internal static char EscapedAscii(char digit, char next)
-        {
-            if (!(((digit >= '0') && (digit <= '9'))
-                || ((digit >= 'A') && (digit <= 'F'))
-                || ((digit >= 'a') && (digit <= 'f'))))
-            {
-                return Uri.c_DummyChar;
-            }
-
-            int res = (digit <= '9')
-                ? ((int)digit - (int)'0')
-                : (((digit <= 'F')
-                ? ((int)digit - (int)'A')
-                : ((int)digit - (int)'a'))
-                   + 10);
-
-            if (!(((next >= '0') && (next <= '9'))
-                || ((next >= 'A') && (next <= 'F'))
-                || ((next >= 'a') && (next <= 'f'))))
-            {
-                return Uri.c_DummyChar;
-            }
-
-            return (char)((res << 4) + ((next <= '9')
-                    ? ((int)next - (int)'0')
-                    : (((next <= 'F')
-                        ? ((int)next - (int)'A')
-                        : ((int)next - (int)'a'))
-                       + 10)));
-        }
-
-        internal const string RFC3986ReservedMarks = @";/?:@&=+$,#[]!'()*";
-        private const string RFC2396ReservedMarks = @";/?:@&=+$,";
-        private const string RFC3986UnreservedMarks = @"-_.~";
-        private const string RFC2396UnreservedMarks = @"-_.~*'()!";
-        private const string AdditionalUnsafeToUnescape = @"%\#";// While not specified as reserved, these are still unsafe to unescape.
-
-        // When unescaping in safe mode, do not unescape the RFC 3986 reserved set:
-        // gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
-        // sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
-        //             / "*" / "+" / "," / ";" / "="
-        //
-        // In addition, do not unescape the following unsafe characters:
-        // excluded    = "%" / "\"
-        //
-        // This implementation used to use the following variant of the RFC 2396 reserved set. 
-        // That behavior is now off by default, but can be enabled by an App Context Switch.
-        // reserved    = ";" | "/" | "?" | "@" | "&" | "=" | "+" | "$" | ","
-        // excluded    = control | "#" | "%" | "\"
-        internal static bool IsNotSafeForUnescape(char ch)
-        {
-            if (ch <= '\x1F' || (ch >= '\x7F' && ch <= '\x9F'))
-            {
-                return true;
-            }
-            else if (UriParser.DontEnableStrictRFC3986ReservedCharacterSets)
-            {
-                if ((ch != ':' && (RFC2396ReservedMarks.IndexOf(ch) >= 0) || (AdditionalUnsafeToUnescape.IndexOf(ch) >= 0)))
-                {
-                    return true;
-                }
-            }
-            else if ((RFC3986ReservedMarks.IndexOf(ch) >= 0) || (AdditionalUnsafeToUnescape.IndexOf(ch) >= 0))
-            {
-                return true;
-            }
-
-            return false;
-        }
-
-        private static unsafe bool IsReservedUnreservedOrHash(char c)
-        {
-            if (IsUnreserved(c))
-            {
-                return true;
-            }
-            if (UriParser.ShouldUseLegacyV2Quirks)
-            {
-                return ((RFC2396ReservedMarks.IndexOf(c) >= 0) || c == '#');
-            }
-            return (RFC3986ReservedMarks.IndexOf(c) >= 0);
-        }
-
-        internal static unsafe bool IsUnreserved(char c)
-        {
-            if (Uri.IsAsciiLetterOrDigit(c))
-            {
-                return true;
-            }
-            if (UriParser.ShouldUseLegacyV2Quirks)
-            {
-                return (RFC2396UnreservedMarks.IndexOf(c) >= 0);
-            }
-            return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
-        }
-
-        internal static bool Is3986Unreserved(char c)
-        {
-            if (Uri.IsAsciiLetterOrDigit(c))
-            {
-                return true;
-            }
-            return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
-        }
-    }
-}
+// namespace System 
+// {
+//     using System.Globalization;
+//     using System.Text;
+//     using System.Diagnostics;
+//     
+//     internal static class UriHelper
+//     {
+//         private static readonly char[] HexUpperChars = {
+//                                    '0', '1', '2', '3', '4', '5', '6', '7',
+//                                    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+//         
+//         // http://host/Path/Path/File?Query is the base of
+//         //      - http://host/Path/Path/File/ ...    (those "File" words may be different in semantic but anyway)
+//         //      - http://host/Path/Path/#Fragment
+//         //      - http://host/Path/Path/?Query
+//         //      - http://host/Path/Path/MoreDir/ ...
+//         //      - http://host/Path/Path/OtherFile?Query
+//         //      - http://host/Path/Path/Fl
+//         //      - http://host/Path/Path/
+//         //
+//         //  It is not a base for
+//         //      - http://host/Path/Path         (that last "Path" is not considered as a directory)
+//         //      - http://host/Path/Path?Query
+//         //      - http://host/Path/Path#Fragment
+//         //      - http://host/Path/Path2/
+//         //      - http://host/Path/Path2/MoreDir
+//         //      - http://host/Path/File
+//         //
+//         // ASSUMES that strings like http://host/Path/Path/MoreDir/../../  have been canonicalized before going to this method.
+//         // ASSUMES that back slashes already have been converted if applicable.
+//         //
+//         internal static unsafe bool TestForSubPath(  char* pMe,  ushort meLength, char* pShe, ushort sheLength, 
+//             bool ignoreCase) 
+//         {
+//             ushort i = 0;
+//             char chMe;
+//             char chShe;
+//
+//             bool AllSameBeforeSlash = true;
+//
+//             for( ;i < meLength && i < sheLength; ++i)
+//             {
+//                 chMe  = *(pMe+i);
+//                 chShe = *(pShe+i);
+//
+//                 if (chMe == '?' || chMe == '#') 
+//                 {
+//                     // survived so far and pMe does not have any more path segments
+//                     return true;
+//                 }
+//
+//                 // If pMe terminates a path segment, so must pShe
+//                 if (chMe == '/') 
+//                 {
+//                     if (chShe != '/') 
+//                     {
+//                         // comparison has falied
+//                         return false;
+//                     }
+//                     // plus the segments must be the same
+//                     if (!AllSameBeforeSlash) 
+//                     {
+//                         // comparison has falied
+//                         return false;
+//                     }
+//                     //so far so good
+//                     AllSameBeforeSlash = true;
+//                     continue;
+//                 }
+//
+//                 // if pShe terminates then pMe must not have any more path segments
+//                 if (chShe == '?' || chShe == '#') 
+//                 {
+//                     break;
+//                 }
+//
+//                 if (!ignoreCase) 
+//                 {
+//                     if (chMe != chShe) 
+//                     {
+//                         AllSameBeforeSlash = false;
+//                     }
+//                 }
+//                 else 
+//                 {
+//                     if (Char.ToLower(chMe, CultureInfo.InvariantCulture) != Char.ToLower(chShe, CultureInfo.InvariantCulture)) 
+//                     {
+//                         AllSameBeforeSlash = false;
+//                     }
+//                 }
+//             }
+//
+//             // If me is longer then it must not have any more path segments
+//             for (; i < meLength; ++i) 
+//             {
+//                 if ((chMe = *(pMe+i)) == '?' || chMe == '#') 
+//                 {
+//                     return true;
+//                 }
+//                 if (chMe == '/') 
+//                 {
+//                     return false;
+//                 }
+//             }
+//             //survived by getting to the end of pMe
+//             return true;
+//         }
+//
+//         // - forceX characters are always escaped if found
+//         // - rsvd character will remain unescaped
+//         //
+//         // start    - starting offset from input
+//         // end      - the exclusive ending offset in input
+//         // destPos  - starting offset in dest for output, on return this will be an exclusive "end" in the output.
+//         //
+//         // In case "dest" has lack of space it will be reallocated by preserving the _whole_ content up to current destPos
+//         //
+//         // Returns null if nothing has to be escaped AND passed dest was null, otherwise the resulting array with the updated destPos
+//         //
+//         const short c_MaxAsciiCharsReallocate   = 40;
+//         const short c_MaxUnicodeCharsReallocate = 40;
+//         const short c_MaxUTF_8BytesPerUnicodeChar  = 4;
+//         const short c_EncodedCharsPerByte = 3;
+//         internal unsafe static char[] EscapeString(string input, int start, int end, char[] dest, ref int destPos, 
+//             bool isUriString, char force1, char force2, char rsvd)
+//         {
+//             if (end - start >= Uri.c_MaxUriBufferSize)
+//                 throw new UriFormatException(SR.GetString(SR.net_uri_SizeLimit));
+//
+//             int i = start;
+//             int prevInputPos = start;
+//             byte *bytes = stackalloc byte[c_MaxUnicodeCharsReallocate*c_MaxUTF_8BytesPerUnicodeChar];   // 40*4=160
+//
+//             fixed (char* pStr = input)
+//             {
+//                 for(; i < end; ++i)
+//                 {
+//                     char ch = pStr[i];
+//
+//                     // a Unicode ?
+//                     if (ch  > '\x7F')
+//                     {
+//                         short maxSize = (short)Math.Min(end - i, (int)c_MaxUnicodeCharsReallocate-1);
+//
+//                         short count = 1;
+//                         for (; count < maxSize && pStr[i + count] > '\x7f'; ++count)
+//                             ;
+//
+//                         // Is the last a high surrogate?
+//                         if (pStr[i + count-1] >= 0xD800 && pStr[i + count-1] <= 0xDBFF)
+//                         {
+//                             // Should be a rare case where the app tries to feed an invalid Unicode surrogates pair
+//                            if (count == 1 || count == end - i)
+//                                 throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
+//                            // need to grab one more char as a Surrogate except when it's a bogus input
+//                            ++count;
+//                         }
+//
+//                         dest = EnsureDestinationSize(pStr, dest, i, 
+//                             (short)(count * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte), 
+//                             c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte,
+//                             ref destPos, prevInputPos);
+//
+//                         short numberOfBytes = (short)Encoding.UTF8.GetBytes(pStr+i, count, bytes, 
+//                             c_MaxUnicodeCharsReallocate*c_MaxUTF_8BytesPerUnicodeChar);
+//
+//                         // This is the only exception that built in UriParser can throw after a Uri ctor.
+//                         // Should not happen unless the app tries to feed an invalid Unicode String
+//                         if (numberOfBytes == 0)
+//                             throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
+//
+//                         i += (count-1);
+//
+//                         for (count = 0 ; count < numberOfBytes; ++count)
+//                             EscapeAsciiChar((char)bytes[count], dest, ref destPos);
+//
+//                         prevInputPos = i+1;
+//                     }
+//                     else if (ch == '%' && rsvd == '%')
+//                     {
+//                         // Means we don't reEncode '%' but check for the possible escaped sequence
+//                         dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte, 
+//                             c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+//                         if(i + 2 < end && EscapedAscii(pStr[i+1], pStr[i+2]) != Uri.c_DummyChar)
+//                         {
+//                             // leave it escaped
+//                             dest[destPos++] = '%';
+//                             dest[destPos++] = pStr[i+1];
+//                             dest[destPos++] = pStr[i+2];
+//                             i += 2;
+//                         }
+//                         else
+//                         {
+//                             EscapeAsciiChar('%', dest, ref destPos);
+//                         }
+//                         prevInputPos = i+1;
+//                     }
+//                     else if (ch == force1 ||  ch == force2)
+//                     {
+//                         dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte, 
+//                             c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+//                         EscapeAsciiChar(ch, dest, ref destPos);
+//                         prevInputPos = i+1;
+//                     }
+//                     else if (ch != rsvd && (isUriString ? !IsReservedUnreservedOrHash(ch) : !IsUnreserved(ch)))
+//                     {
+//                         dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte, 
+//                             c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+//                         EscapeAsciiChar(ch, dest, ref destPos);
+//                         prevInputPos = i+1;
+//                     }
+//                 }
+//
+//                 if (prevInputPos != i)
+//                 {
+//                     // need to fill up the dest array ?
+//                     if (prevInputPos != start || dest != null)
+//                         dest = EnsureDestinationSize(pStr, dest, i, 0, 0, ref destPos, prevInputPos);
+//                 }
+//             }
+//
+//             return dest;
+//         }
+//
+//         //
+//         // ensure destination array has enough space and contains all the needed input stuff
+//         //
+//         private unsafe static char[] EnsureDestinationSize(char* pStr, char[] dest, int currentInputPos, 
+//             short charsToAdd, short minReallocateChars, ref int destPos, int prevInputPos)
+//         {
+//             if ((object) dest == null || dest.Length  < destPos + (currentInputPos-prevInputPos) + charsToAdd)
+//             {
+//                 // allocating or reallocating array by ensuring enough space based on maxCharsToAdd.
+//                 char[] newresult = new char[destPos + (currentInputPos-prevInputPos) + minReallocateChars];
+//
+//                 if ((object) dest != null && destPos != 0)
+//                     Buffer.BlockCopy(dest, 0, newresult, 0, destPos<<1);
+//                 dest = newresult;
+//             }
+//
+//             // ensuring we copied everything form the input string left before last escaping
+//             while (prevInputPos != currentInputPos)
+//                 dest[destPos++] = pStr[prevInputPos++];
+//             return dest;
+//         }
+//         
+//         //
+//         // This method will assume that any good Escaped Sequence will be unescaped in the output
+//         // - Assumes Dest.Length - detPosition >= end-start
+//         // - UnescapeLevel controls various modes of opearion
+//         // - Any "bad" escape sequence will remain as is or '%' will be escaped.
+//         // - destPosition tells the starting index in dest for placing the result.
+//         //   On return destPosition tells the last character + 1 postion in the "dest" array.
+//         // - The control chars and chars passed in rsdvX parameters may be re-escaped depending on UnescapeLevel
+//         // - It is a RARE case when Unescape actually needs escaping some characteres mentioned above.
+//         //   For this reason it returns a char[] that is usually the same ref as the input "dest" value.
+//         //
+//         internal unsafe static char[] UnescapeString(string input, int start, int end, char[] dest, 
+//             ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, 
+//             bool isQuery)
+//         {
+//             fixed (char *pStr = input)
+//             {
+//                 return UnescapeString(pStr, start, end, dest, ref destPosition, rsvd1, rsvd2, rsvd3, unescapeMode, 
+//                     syntax, isQuery);
+//             }
+//         }
+//         internal unsafe static char[] UnescapeString(char* pStr, int start, int end, char[] dest, ref int destPosition, 
+//             char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery)
+//         {
+//             byte [] bytes = null;
+//             byte escapedReallocations = 0;
+//             bool escapeReserved = false;
+//             int next = start;
+//             bool iriParsing = Uri.IriParsingStatic(syntax)
+//                                 && ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.EscapeUnescape);
+//             
+//             while (true)
+//             {
+//                 // we may need to re-pin dest[]
+//                 fixed (char* pDest = dest)
+//                 {
+//                     if ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.CopyOnly)
+//                     {
+//                         while (start < end)
+//                             pDest[destPosition++] = pStr[start++];
+//                         return dest;
+//                     }
+//
+//                     while (true)
+//                     {
+//                         char ch = (char)0;
+//
+//                         for (;next < end; ++next)
+//                         {
+//                             if ((ch = pStr[next]) == '%')
+//                             {
+//                                 if ((unescapeMode & UnescapeMode.Unescape) == 0)
+//                                 {
+//                                     // re-escape, don't check anything else
+//                                     escapeReserved = true;
+//                                 }
+//                                 else if (next+2 < end)
+//                                 {
+//                                     ch = EscapedAscii(pStr[next+1], pStr[next+2]);
+//                                     // Unescape a good sequence if full unescape is requested
+//                                     if (unescapeMode >= UnescapeMode.UnescapeAll)
+//                                     {
+//                                         if (ch == Uri.c_DummyChar)
+//                                         {
+//                                             if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
+//                                             {
+//                                                 // Should be a rare case where the app tries to feed an invalid escaped sequence
+//                                                 throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
+//                                             }
+//                                             continue;
+//                                         }
+//                                     }
+//                                     // re-escape % from an invalid sequence
+//                                     else if (ch == Uri.c_DummyChar)
+//                                     {
+//                                         if ((unescapeMode & UnescapeMode.Escape) != 0)
+//                                             escapeReserved = true;
+//                                         else
+//                                             continue;   // we should throw instead but since v1.0 would just print '%'
+//                                     }
+//                                     // Do not unescape '%' itself unless full unescape is requested
+//                                     else if (ch == '%')
+//                                     {
+//                                         next += 2;
+//                                         continue;
+//                                     }
+//                                     // Do not unescape a reserved char unless full unescape is requested
+//                                     else if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
+//                                     {
+//                                         next += 2;
+//                                         continue;
+//                                     }
+//                                     // Do not unescape a dangerous char unless it's V1ToStringFlags mode
+//                                     else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 && IsNotSafeForUnescape(ch))
+//                                     {
+//                                         next += 2;
+//                                         continue;
+//                                     }
+//                                     else if (iriParsing && ((ch <='\x9F' && IsNotSafeForUnescape(ch)) || 
+//                                                             (ch >'\x9F' &&!IriHelper.CheckIriUnicodeRange(ch, isQuery))))
+//                                     {
+//                                         // check if unenscaping gives a char ouside iri range 
+//                                         // if it does then keep it escaped
+//                                         next += 2;
+//                                         continue;
+//                                     }
+//                                     // unescape escaped char or escape %
+//                                     break;
+//                                 }
+//                                 else if (unescapeMode >= UnescapeMode.UnescapeAll)
+//                                 {
+//                                     if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
+//                                     {
+//                                         // Should be a rare case where the app tries to feed an invalid escaped sequence
+//                                         throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
+//                                     }
+//                                     // keep a '%' as part of a bogus sequence 
+//                                     continue;
+//                                 }
+//                                 else
+//                                 {
+//                                     escapeReserved = true;
+//                                 }
+//                                 // escape (escapeReserved==ture) or otheriwse unescape the sequence
+//                                 break;
+//                             }
+//                             else if ((unescapeMode & (UnescapeMode.Unescape | UnescapeMode.UnescapeAll)) 
+//                                 == (UnescapeMode.Unescape | UnescapeMode.UnescapeAll))
+//                             {
+//                                 continue;
+//                             }
+//                             else if ((unescapeMode & UnescapeMode.Escape) != 0)
+//                             {
+//                                  // Could actually escape some of the characters
+//                                  if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
+//                                  {
+//                                      // found an unescaped reserved character -> escape it
+//                                      escapeReserved = true;
+//                                      break;
+//                                  }
+//                                  else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 
+//                                      && (ch <= '\x1F' || (ch >= '\x7F' && ch <= '\x9F')))
+//                                  {
+//                                      // found an unescaped reserved character -> escape it
+//                                      escapeReserved = true;
+//                                      break;
+//                                  }
+//                             }
+//                         }
+//
+//                         //copy off previous characters from input
+//                         while (start < next)
+//                             pDest[destPosition++] = pStr[start++];
+//
+//                         if (next != end)
+//                         {
+//                             //VsWhidbey#87423
+//                             if (escapeReserved)
+//                             {
+//                                 //escape that char
+//                                 // Since this should be _really_ rare case, reallocate with constant size increase of 30 rsvd-type characters.
+//                                 if (escapedReallocations == 0)
+//                                 {
+//                                     escapedReallocations = 30;
+//                                     char[] newDest = new char[dest.Length + escapedReallocations*3];
+//                                     fixed (char *pNewDest = newDest)
+//                                     {
+//                                         for (int i = 0; i < destPosition; ++i)
+//                                             pNewDest[i] = pDest[i];
+//                                     }
+//                                     dest = newDest;
+//                                     // re-pin new dest[] array
+//                                     goto dest_fixed_loop_break;
+//                                 }
+//                                 else
+//                                 {
+//                                     --escapedReallocations;
+//                                     EscapeAsciiChar(pStr[next], dest, ref destPosition);
+//                                     escapeReserved = false;
+//                                     start = ++next;
+//                                     continue;
+//                                 }
+//                             }
+//
+//                             // unescaping either one Ascii or possibly multiple Unicode
+//
+//                             if (ch <= '\x7F')
+//                             {
+//                                 //ASCII
+//                                 dest[destPosition++] = ch;
+//                                 next+=3;
+//                                 start = next;
+//                                 continue;
+//                             }
+//
+//                             // Unicode
+//
+//                             int byteCount = 1;
+//                             // lazy initialization of max size, will reuse the array for next sequences
+//                             if ((object) bytes == null)
+//                                 bytes = new byte[end - next];
+//
+//                             bytes[0] = (byte)ch;
+//                             next+=3;
+//                             while (next < end)
+//                             {
+//                                 // Check on exit criterion
+//                                 if ((ch = pStr[next]) != '%' || next+2 >= end)
+//                                     break;
+//
+//                                 // already made sure we have 3 characters in str
+//                                 ch = EscapedAscii(pStr[next+1], pStr[next+2]);
+//
+//                                 //invalid hex sequence ?
+//                                 if (ch == Uri.c_DummyChar)
+//                                     break;
+//                                 // character is not part of a UTF-8 sequence ?
+//                                 else if (ch < '\x80')
+//                                     break;
+//                                 else
+//                                 {
+//                                     //a UTF-8 sequence
+//                                     bytes[byteCount++] = (byte)ch;
+//                                     next += 3;
+//                                 }
+//                             }
+//                             Encoding noFallbackCharUTF8 = (Encoding)Encoding.UTF8.Clone();
+//                             noFallbackCharUTF8.EncoderFallback = new EncoderReplacementFallback("");
+//                             noFallbackCharUTF8.DecoderFallback = new DecoderReplacementFallback("");
+//
+//                             char[] unescapedChars = new char[bytes.Length];
+//                             int charCount = noFallbackCharUTF8.GetChars(bytes, 0, byteCount, unescapedChars, 0);
+//
+//                             start = next;
+//
+//                             // match exact bytes
+//                             // Do not unescape chars not allowed by Iri
+//                             // need to check for invalid utf sequences that may not have given any chars
+//
+//                             MatchUTF8Sequence(pDest, dest, ref destPosition, unescapedChars, charCount, bytes, 
+//                                 byteCount, isQuery, iriParsing);
+//                         }
+//
+//                         if (next == end)
+//                             goto done;
+//                     }
+// dest_fixed_loop_break: ;
+//                 }
+//             }
+//
+// done:       return dest;
+//         }
+//
+//         //
+//         // Need to check for invalid utf sequences that may not have given any chars.
+//         // We got the unescaped chars, we then reencode them and match off the bytes
+//         // to get the invalid sequence bytes that we just copy off
+//         //
+//         internal static unsafe void MatchUTF8Sequence(char* pDest, char[] dest, ref int destOffset, char[] unescapedChars,
+//             int charCount, byte[] bytes, int byteCount, bool isQuery, bool iriParsing)
+//         {
+//             int count = 0;
+//             fixed (char* unescapedCharsPtr = unescapedChars)
+//             {
+//                 for (int j = 0; j < charCount; ++j)
+//                 {
+//                     bool isHighSurr = Char.IsHighSurrogate(unescapedCharsPtr[j]);
+//
+//                     byte[] encodedBytes = Encoding.UTF8.GetBytes(unescapedChars, j, isHighSurr ? 2 : 1);
+//                     int encodedBytesLength = encodedBytes.Length;
+//
+//                     // we have to keep unicode chars outside Iri range escaped
+//                     bool inIriRange = false;
+//                     if (iriParsing) 
+//                     {
+//                         if (!isHighSurr)
+//                             inIriRange = IriHelper.CheckIriUnicodeRange(unescapedChars[j], isQuery);
+//                         else 
+//                         {
+//                             bool surrPair = false;
+//                             inIriRange = IriHelper.CheckIriUnicodeRange(unescapedChars[j], unescapedChars[j + 1],
+//                                                                    ref surrPair, isQuery);
+//                         }
+//                     }
+//
+//                     while (true)
+//                     {
+//                         // Escape any invalid bytes that were before this character
+//                         while (bytes[count] != encodedBytes[0])
+//                         {
+//                             Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
+//                             EscapeAsciiChar((char)bytes[count++], dest, ref destOffset);
+//                         }
+//
+//                         // check if all bytes match
+//                         bool allBytesMatch = true;
+//                         int k = 0;
+//                         for (; k < encodedBytesLength; ++k)
+//                         {
+//                             if (bytes[count + k] != encodedBytes[k])
+//                             {
+//                                 allBytesMatch = false;
+//                                 break;
+//                             }
+//                         }
+//
+//                         if (allBytesMatch)
+//                         {
+//                             count += encodedBytesLength;
+//                             if (iriParsing)
+//                             {
+//                                 if (!inIriRange)
+//                                 {
+//                                     // need to keep chars not allowed as escaped
+//                                     for (int l = 0; l < encodedBytes.Length; ++l)
+//                                     {
+//                                         Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
+//                                         EscapeAsciiChar((char)encodedBytes[l], dest, ref destOffset);
+//                                     }
+//                                 }
+//                                 else if (!Uri.IsBidiControlCharacter(unescapedCharsPtr[j]) || !UriParser.DontKeepUnicodeBidiFormattingCharacters)
+//                                 {
+//                                     //copy chars
+//                                     Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
+//                                     pDest[destOffset++] = unescapedCharsPtr[j];
+//                                     if (isHighSurr)
+//                                     {
+//                                         Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
+//                                         pDest[destOffset++] = unescapedCharsPtr[j + 1];
+//                                     }
+//                                 }
+//                             }
+//                             else
+//                             {
+//                                 //copy chars
+//                                 Debug.Assert(dest.Length > destOffset);
+//                                 pDest[destOffset++] = unescapedCharsPtr[j];
+//
+//                                 if (isHighSurr)
+//                                 {
+//                                     Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
+//                                     pDest[destOffset++] = unescapedCharsPtr[j + 1];
+//                                 }
+//                             }
+//
+//                             break; // break out of while (true) since we've matched this char bytes
+//                         }
+//                         else
+//                         {
+//                             // copy bytes till place where bytes dont match
+//                             for (int l = 0; l < k; ++l)
+//                             {
+//                                 Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
+//                                 EscapeAsciiChar((char)bytes[count++], dest, ref destOffset);
+//                             }
+//                         }
+//                     }
+//
+//                     if (isHighSurr) j++;
+//
+//                 }
+//             }
+//
+//             // Include any trailing invalid sequences
+//             while (count < byteCount) 
+//             {
+//                 Debug.Assert(dest.Length > destOffset, "Buffer overrun detected");
+//                 EscapeAsciiChar((char)bytes[count++], dest, ref destOffset);
+//             }
+//         }
+//
+//         internal static void EscapeAsciiChar(char ch, char[] to, ref int pos)
+//         {
+//             to[pos++] = '%';
+//             to[pos++] = HexUpperChars[(ch & 0xf0) >> 4];
+//             to[pos++] = HexUpperChars[ch & 0xf];
+//         }
+//
+//         internal static char EscapedAscii(char digit, char next)
+//         {
+//             if (!(((digit >= '0') && (digit <= '9'))
+//                 || ((digit >= 'A') && (digit <= 'F'))
+//                 || ((digit >= 'a') && (digit <= 'f'))))
+//             {
+//                 return Uri.c_DummyChar;
+//             }
+//
+//             int res = (digit <= '9')
+//                 ? ((int)digit - (int)'0')
+//                 : (((digit <= 'F')
+//                 ? ((int)digit - (int)'A')
+//                 : ((int)digit - (int)'a'))
+//                    + 10);
+//
+//             if (!(((next >= '0') && (next <= '9'))
+//                 || ((next >= 'A') && (next <= 'F'))
+//                 || ((next >= 'a') && (next <= 'f'))))
+//             {
+//                 return Uri.c_DummyChar;
+//             }
+//
+//             return (char)((res << 4) + ((next <= '9')
+//                     ? ((int)next - (int)'0')
+//                     : (((next <= 'F')
+//                         ? ((int)next - (int)'A')
+//                         : ((int)next - (int)'a'))
+//                        + 10)));
+//         }
+//
+//         internal const string RFC3986ReservedMarks = @";/?:@&=+$,#[]!'()*";
+//         private const string RFC2396ReservedMarks = @";/?:@&=+$,";
+//         private const string RFC3986UnreservedMarks = @"-_.~";
+//         private const string RFC2396UnreservedMarks = @"-_.~*'()!";
+//         private const string AdditionalUnsafeToUnescape = @"%\#";// While not specified as reserved, these are still unsafe to unescape.
+//
+//         // When unescaping in safe mode, do not unescape the RFC 3986 reserved set:
+//         // gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
+//         // sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
+//         //             / "*" / "+" / "," / ";" / "="
+//         //
+//         // In addition, do not unescape the following unsafe characters:
+//         // excluded    = "%" / "\"
+//         //
+//         // This implementation used to use the following variant of the RFC 2396 reserved set. 
+//         // That behavior is now off by default, but can be enabled by an App Context Switch.
+//         // reserved    = ";" | "/" | "?" | "@" | "&" | "=" | "+" | "$" | ","
+//         // excluded    = control | "#" | "%" | "\"
+//         internal static bool IsNotSafeForUnescape(char ch)
+//         {
+//             if (ch <= '\x1F' || (ch >= '\x7F' && ch <= '\x9F'))
+//             {
+//                 return true;
+//             }
+//             else if (UriParser.DontEnableStrictRFC3986ReservedCharacterSets)
+//             {
+//                 if ((ch != ':' && (RFC2396ReservedMarks.IndexOf(ch) >= 0) || (AdditionalUnsafeToUnescape.IndexOf(ch) >= 0)))
+//                 {
+//                     return true;
+//                 }
+//             }
+//             else if ((RFC3986ReservedMarks.IndexOf(ch) >= 0) || (AdditionalUnsafeToUnescape.IndexOf(ch) >= 0))
+//             {
+//                 return true;
+//             }
+//
+//             return false;
+//         }
+//
+//         private static unsafe bool IsReservedUnreservedOrHash(char c)
+//         {
+//             if (IsUnreserved(c))
+//             {
+//                 return true;
+//             }
+//             if (UriParser.ShouldUseLegacyV2Quirks)
+//             {
+//                 return ((RFC2396ReservedMarks.IndexOf(c) >= 0) || c == '#');
+//             }
+//             return (RFC3986ReservedMarks.IndexOf(c) >= 0);
+//         }
+//
+//         internal static unsafe bool IsUnreserved(char c)
+//         {
+//             if (Uri.IsAsciiLetterOrDigit(c))
+//             {
+//                 return true;
+//             }
+//             if (UriParser.ShouldUseLegacyV2Quirks)
+//             {
+//                 return (RFC2396UnreservedMarks.IndexOf(c) >= 0);
+//             }
+//             return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
+//         }
+//
+//         internal static bool Is3986Unreserved(char c)
+//         {
+//             if (Uri.IsAsciiLetterOrDigit(c))
+//             {
+//                 return true;
+//             }
+//             return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
+//         }
+//     }
+// }
diff --git a/System/net/System/_UriSyntax.cs b/System/net/System/_UriSyntax.cs
index 07c34d3..e3c9256 100644
--- a/System/net/System/_UriSyntax.cs
+++ b/System/net/System/_UriSyntax.cs
@@ -1,644 +1,644 @@
-//------------------------------------------------------------------------------
-// <copyright file="_UriSyntax.cs" company="Microsoft">
-//     Copyright (c) Microsoft Corporation.  All rights reserved.
-// </copyright>
-//------------------------------------------------------------------------------
-
-    //
-    // This file utilizes partial class feature and contains
-    // only internal implementation of UriParser type
-    //
-
-namespace System {
-
-    using System.Collections.Generic;
-    using System.Diagnostics;
-    using System.Runtime.Versioning;
-
-    // This enum specifies the Uri syntax flags that is understood by builtin Uri parser.
-    [Flags]
-    internal enum UriSyntaxFlags {
-        None                    = 0x0,
-
-        MustHaveAuthority       = 0x1,  // must have "//" after scheme:
-        OptionalAuthority       = 0x2,  // used by generic parser due to unknown Uri syntax
-        MayHaveUserInfo         = 0x4,
-        MayHavePort             = 0x8,
-        MayHavePath             = 0x10,
-        MayHaveQuery            = 0x20,
-        MayHaveFragment         = 0x40,
-
-        AllowEmptyHost          = 0x80,
-        AllowUncHost            = 0x100,
-        AllowDnsHost            = 0x200,
-        AllowIPv4Host           = 0x400,
-        AllowIPv6Host           = 0x800,
-        AllowAnInternetHost     = AllowDnsHost|AllowIPv4Host|AllowIPv6Host,
-        AllowAnyOtherHost       = 0x1000, // Relaxed authority syntax
-
-        FileLikeUri             = 0x2000, //Special case to allow file:\\balbla or file://\\balbla
-        MailToLikeUri           = 0x4000, //V1 parser inheritance mailTo:AuthorityButNoSlashes
-
-        V1_UnknownUri           = 0x10000, // a Compatibility with V1 parser for an unknown scheme
-        SimpleUserSyntax        = 0x20000, // It is safe to not call virtual UriParser methods
-        BuiltInSyntax           = 0x40000, // This is a simple Uri plus it is hardcoded in the product
-        ParserSchemeOnly        = 0x80000, // This is a Parser that does only Uri scheme parsing
-
-        AllowDOSPath            = 0x100000,  // will check for "x:\"
-        PathIsRooted            = 0x200000,  // For an authority based Uri the first path char is '/'
-        ConvertPathSlashes      = 0x400000,  // will turn '\' into '/'
-        CompressPath            = 0x800000,  // For an authority based Uri remove/compress /./ /../ in the path
-        CanonicalizeAsFilePath  = 0x1000000, // remove/convert sequences /.../ /x../ /x./ dangerous for a DOS path
-        UnEscapeDotsAndSlashes  = 0x2000000, // additionally unescape dots and slashes before doing path compression
-        AllowIdn                = 0x4000000,    // IDN host conversion allowed
-        AllowIriParsing         = 0x10000000,   // Iri parsing. String is normalized, bidi control 
-                                                // characters are removed, unicode char limits are checked etc.
-
-//      KeepTailLWS             = 0x8000000,
-    }
-
-    //
-    // Only internal members are included here
-    //
-    public abstract partial class UriParser {
-        private static readonly Dictionary<String, UriParser> m_Table;
-        private static Dictionary<String, UriParser> m_TempTable;
-
-        private UriSyntaxFlags m_Flags;
-        
-        // Some flags (specified in c_UpdatableFlags) besides being set in the ctor, can also be set at a later
-        // point. Such "updatable" flags can be set using SetUpdatableFlags(); if this method is called,
-        // the value specified in the ctor is ignored (i.e. for all c_UpdatableFlags the value in m_Flags is
-        // ignored), and the new value is used (i.e. for all c_UpdatableFlags the value in m_UpdatableFlags is used).
-        private volatile UriSyntaxFlags m_UpdatableFlags;
-        private volatile bool m_UpdatableFlagsUsed;
-
-        // The following flags can be updated at any time.
-        private const UriSyntaxFlags c_UpdatableFlags = UriSyntaxFlags.UnEscapeDotsAndSlashes;
-        
-        private int m_Port;
-        private string m_Scheme;
-
-        internal const int NoDefaultPort = -1;
-        private const int c_InitialTableSize = 25;
-
-        // These are always available without paying hashtable lookup cost
-        // Note: see UpdateStaticSyntaxReference()
-        internal static UriParser HttpUri;
-        internal static UriParser HttpsUri;
-        internal static UriParser WsUri;
-        internal static UriParser WssUri;
-        internal static UriParser FtpUri;
-        internal static UriParser FileUri;
-        internal static UriParser GopherUri;
-        internal static UriParser NntpUri;
-        internal static UriParser NewsUri;
-        internal static UriParser MailToUri;
-        internal static UriParser UuidUri;
-        internal static UriParser TelnetUri;
-        internal static UriParser LdapUri;
-        internal static UriParser NetTcpUri;
-        internal static UriParser NetPipeUri;
-
-        internal static UriParser VsMacrosUri; //bad guy
-
-        
-        private enum UriQuirksVersion {
-            // V1 = 1, // RFC 1738 - Not supported
-            V2 = 2, // RFC 2396
-            V3 = 3, // RFC 3986, 3987
-        }
-
-        // Store in a static field to allow for test manipulation and emergency workarounds via reflection.
-        // Note this is not placed in the Uri class in order to avoid circular static dependencies.
-        private static readonly UriQuirksVersion s_QuirksVersion = 
-            (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5
-                 // || BinaryCompatibility.TargetsAtLeast_Silverlight_V6
-                 // || BinaryCompatibility.TargetsAtLeast_Phone_V8_0
-                 ) ? UriQuirksVersion.V3 : UriQuirksVersion.V2;
-
-        internal static bool ShouldUseLegacyV2Quirks {
-            get {
-                return s_QuirksVersion <= UriQuirksVersion.V2;
-            }
-        }
-
-        internal static bool DontEnableStrictRFC3986ReservedCharacterSets
-        {
-            get {
-                return LocalAppContextSwitches.DontEnableStrictRFC3986ReservedCharacterSets;
-            }
-        }
-
-        internal static bool DontKeepUnicodeBidiFormattingCharacters
-        {
-            get
-            {
-                return LocalAppContextSwitches.DontKeepUnicodeBidiFormattingCharacters;
-            }
-        }
-
-        static UriParser() {
-
-            m_Table = new Dictionary<String, UriParser>(c_InitialTableSize);
-            m_TempTable = new Dictionary<String, UriParser>(c_InitialTableSize);
-
-            //Now we will call for the instance constructors that will interrupt this static one.
-
-            // Below we simulate calls into FetchSyntax() but avoid using lock() and other things redundant for a .cctor
-
-            HttpUri   = new BuiltInUriParser("http", 80, HttpSyntaxFlags);
-            m_Table[HttpUri.SchemeName] = HttpUri;                   //HTTP
-
-            HttpsUri  = new BuiltInUriParser("https", 443, HttpUri.m_Flags);
-            m_Table[HttpsUri.SchemeName] = HttpsUri;                  //HTTPS cloned from HTTP
-
-            WsUri = new BuiltInUriParser("ws", 80, HttpSyntaxFlags);
-            m_Table[WsUri.SchemeName] = WsUri;                   // WebSockets
-
-            WssUri = new BuiltInUriParser("wss", 443, HttpSyntaxFlags);
-            m_Table[WssUri.SchemeName] = WssUri;                  // Secure WebSockets
-
-            FtpUri    = new BuiltInUriParser("ftp", 21, FtpSyntaxFlags);
-            m_Table[FtpUri.SchemeName] = FtpUri;                    //FTP
-
-            FileUri   = new BuiltInUriParser("file", NoDefaultPort, FileSyntaxFlags);
-            m_Table[FileUri.SchemeName] = FileUri;                   //FILE
-
-            GopherUri = new BuiltInUriParser("gopher", 70, GopherSyntaxFlags);
-            m_Table[GopherUri.SchemeName] = GopherUri;                 //GOPHER
-
-            NntpUri   = new BuiltInUriParser("nntp", 119, NntpSyntaxFlags);
-            m_Table[NntpUri.SchemeName] = NntpUri;                   //NNTP
-
-            NewsUri   = new BuiltInUriParser("news", NoDefaultPort, NewsSyntaxFlags);
-            m_Table[NewsUri.SchemeName] = NewsUri;                   //NEWS
-
-            MailToUri = new BuiltInUriParser("mailto", 25, MailtoSyntaxFlags);
-            m_Table[MailToUri.SchemeName] = MailToUri;                 //MAILTO
-
-            UuidUri   = new BuiltInUriParser("uuid", NoDefaultPort, NewsUri.m_Flags);
-            m_Table[UuidUri.SchemeName] = UuidUri;                   //UUID cloned from NEWS
-
-            TelnetUri = new BuiltInUriParser("telnet", 23, TelnetSyntaxFlags);
-            m_Table[TelnetUri.SchemeName] = TelnetUri;                 //TELNET
-
-            LdapUri   = new BuiltInUriParser("ldap", 389, LdapSyntaxFlags);
-            m_Table[LdapUri.SchemeName] = LdapUri;                   //LDAP
-
-            NetTcpUri   = new BuiltInUriParser("net.tcp", 808, NetTcpSyntaxFlags);
-            m_Table[NetTcpUri.SchemeName] = NetTcpUri;   
-
-            NetPipeUri   = new BuiltInUriParser("net.pipe", NoDefaultPort, NetPipeSyntaxFlags);
-            m_Table[NetPipeUri.SchemeName] = NetPipeUri;   
-
-            VsMacrosUri = new BuiltInUriParser("vsmacros", NoDefaultPort, VsmacrosSyntaxFlags);
-            m_Table[VsMacrosUri.SchemeName] = VsMacrosUri;               //VSMACROS
-
-        }
-        //
-        private class BuiltInUriParser: UriParser
-        {
-            //
-            // All BuiltIn parsers use that ctor. They are marked with "simple" and "built-in" flags
-            //
-            internal BuiltInUriParser(string lwrCaseScheme, int defaultPort, UriSyntaxFlags syntaxFlags)
-                : base ((syntaxFlags | UriSyntaxFlags.SimpleUserSyntax | UriSyntaxFlags.BuiltInSyntax))
-            {
-                m_Scheme = lwrCaseScheme;
-                m_Port   = defaultPort;
-            }
-        }
-        //
-        internal UriSyntaxFlags Flags {
-            get {
-                return m_Flags;
-            }
-        }
-        //
-        internal bool NotAny(UriSyntaxFlags flags)
-        {
-            // Return true if none of the flags specified in 'flags' are set.
-            return IsFullMatch(flags, UriSyntaxFlags.None);
-        }
-        //
-        internal bool InFact(UriSyntaxFlags flags)
-        {
-            // Return true if at least one of the flags in 'flags' is set.
-            return !IsFullMatch(flags, UriSyntaxFlags.None);
-        }
-        //
-        internal bool IsAllSet(UriSyntaxFlags flags)
-        {
-            // Return true if all flags in 'flags' are set.
-            return IsFullMatch(flags, flags);
-        }
-
-        private bool IsFullMatch(UriSyntaxFlags flags, UriSyntaxFlags expected)
-        {
-            // Return true, if masking the current set of flags with 'flags' equals 'expected'.
-            // Definition 'current set of flags': 
-            // a) if updatable flags were never set: m_Flags
-            // b) if updatable flags were set: set union between all flags in m_Flags which are not updatable
-            //    (i.e. not part of c_UpdatableFlags) and all flags in m_UpdatableFlags
-
-            UriSyntaxFlags mergedFlags;
-
-            // if none of the flags in 'flags' is an updatable flag, we ignore m_UpdatableFlags
-            if (((flags & c_UpdatableFlags) == 0) || !m_UpdatableFlagsUsed)
-            {
-                mergedFlags = m_Flags;
-            }
-            else
-            {
-                // mask m_Flags to only use the flags not in c_UpdatableFlags
-                mergedFlags = (m_Flags & (~c_UpdatableFlags)) | m_UpdatableFlags;
-            }
-
-            return (mergedFlags & flags) == expected;
-        }
-
-        //
-        // Internal .ctor, any ctor eventually goes through this one
-        //
-        internal UriParser(UriSyntaxFlags flags)
-        {
-            m_Flags = flags;
-            m_Scheme = string.Empty;
-        }
-        //
-        private static void FetchSyntax(UriParser syntax, string lwrCaseSchemeName, int defaultPort)
-        {
-            if (syntax.SchemeName.Length != 0)
-                throw new InvalidOperationException(SR.GetString(SR.net_uri_NeedFreshParser, syntax.SchemeName));
-
-            lock (m_Table)
-            {
-                syntax.m_Flags &= ~UriSyntaxFlags.V1_UnknownUri;
-                UriParser oldSyntax = null;
-                m_Table.TryGetValue(lwrCaseSchemeName, out oldSyntax);
-                if (oldSyntax != null)
-                    throw new InvalidOperationException(SR.GetString(SR.net_uri_AlreadyRegistered, oldSyntax.SchemeName));
-                
-                m_TempTable.TryGetValue(syntax.SchemeName, out oldSyntax);
-                if (oldSyntax != null)
-                {
-                    // optimization on schemeName, will try to keep the first reference
-                    lwrCaseSchemeName = oldSyntax.m_Scheme;
-                    m_TempTable.Remove(lwrCaseSchemeName);
-                }
-
-                syntax.OnRegister(lwrCaseSchemeName, defaultPort);
-                syntax.m_Scheme = lwrCaseSchemeName;
-                syntax.CheckSetIsSimpleFlag();
-                syntax.m_Port = defaultPort;
-
-                m_Table[syntax.SchemeName] = syntax;
-            }
-        }
-        //
-        private const int c_MaxCapacity = 512;
-        //schemeStr must be in lower case!
-        internal static UriParser FindOrFetchAsUnknownV1Syntax(string lwrCaseScheme) {
-
-            // check may be other thread just added one
-            UriParser syntax = null;
-            m_Table.TryGetValue(lwrCaseScheme, out syntax);
-            if (syntax != null) {
-                return syntax;
-            }
-            m_TempTable.TryGetValue(lwrCaseScheme, out syntax);
-            if (syntax != null) {
-                return syntax;
-            }
-            lock (m_Table) {
-                // This is a bit paranoid but let's prevent static table growing infinitly
-                if (m_TempTable.Count >= c_MaxCapacity) {
-                    m_TempTable = new Dictionary<String, UriParser>(c_InitialTableSize);
-                }
-                syntax = new BuiltInUriParser(lwrCaseScheme, NoDefaultPort, UnknownV1SyntaxFlags);
-                m_TempTable[lwrCaseScheme] = syntax;
-                return syntax;
-            }
-        }
-        //
-        internal static UriParser GetSyntax(string lwrCaseScheme) {
-            UriParser ret = null;
-            m_Table.TryGetValue(lwrCaseScheme, out ret);
-            if (ret == null) {
-                m_TempTable.TryGetValue(lwrCaseScheme, out ret);
-            }
-            return ret;
-        }
-        //
-        // Builtin and User Simple syntaxes do not need custom validation/parsing (i.e. virtual method calls),
-        //
-        internal bool IsSimple
-        {
-            get {
-                return InFact(UriSyntaxFlags.SimpleUserSyntax);
-            }
-        }
-        //
-        internal void CheckSetIsSimpleFlag()
-        {
-            Type type  = this.GetType();
-
-            if (    type == typeof(GenericUriParser)     
-                ||  type == typeof(HttpStyleUriParser)   
-                ||  type == typeof(FtpStyleUriParser)   
-                ||  type == typeof(FileStyleUriParser)   
-                ||  type == typeof(NewsStyleUriParser)   
-                ||  type == typeof(GopherStyleUriParser) 
-                ||  type == typeof(NetPipeStyleUriParser) 
-                ||  type == typeof(NetTcpStyleUriParser) 
-                ||  type == typeof(LdapStyleUriParser)
-                )
-            {
-                m_Flags |= UriSyntaxFlags.SimpleUserSyntax;
-            }
-        }
-
-        //
-        // This method is used to update flags. The scenario where this is needed is when the user specifies
-        // flags in the config file. The config file is read after UriParser instances were created.
-        //
-        internal void SetUpdatableFlags(UriSyntaxFlags flags) {
-
-            Debug.Assert(!m_UpdatableFlagsUsed, 
-                "SetUpdatableFlags() already called. It can only be called once per parser.");
-            Debug.Assert((flags & (~c_UpdatableFlags)) == 0, "Only updatable flags can be set.");
-
-            // No locks necessary. Reordering won't happen due to volatile.
-            m_UpdatableFlags = flags;
-            m_UpdatableFlagsUsed = true;
-        }
-
-        //
-        // These are simple internal wrappers that will call virtual protected methods
-        // (to avoid "protected internal" siganures in the public docs)
-        //
-        internal UriParser InternalOnNewUri()
-        {
-            UriParser effectiveParser = OnNewUri();
-            if ((object)this != (object)effectiveParser)
-            {
-                effectiveParser.m_Scheme = m_Scheme;
-                effectiveParser.m_Port   = m_Port;
-                effectiveParser.m_Flags  = m_Flags;
-            }
-            return effectiveParser;
-        }
-
-        //
-        internal void InternalValidate(Uri thisUri, out UriFormatException parsingError)
-        {
-            InitializeAndValidate(thisUri, out parsingError);
-        }
-
-        //
-        internal string InternalResolve(Uri thisBaseUri, Uri uriLink, out UriFormatException parsingError)
-        {
-            return Resolve(thisBaseUri, uriLink, out parsingError);
-        }
-
-        //
-        internal bool InternalIsBaseOf(Uri thisBaseUri, Uri uriLink)
-        {
-            return IsBaseOf(thisBaseUri, uriLink);
-        }
-
-        //
-        internal string InternalGetComponents(Uri thisUri, UriComponents uriComponents, UriFormat uriFormat)
-        {
-            return GetComponents(thisUri, uriComponents, uriFormat);
-        }
-
-        //
-        internal bool InternalIsWellFormedOriginalString(Uri thisUri)
-        {
-            return IsWellFormedOriginalString(thisUri);
-        }
-
-        //
-        // Various Uri scheme syntax flags
-        //
-        private const UriSyntaxFlags UnknownV1SyntaxFlags =
-                                            UriSyntaxFlags.V1_UnknownUri | // This flag must be always set here
-                                            UriSyntaxFlags.OptionalAuthority |
-                                            //
-                                            UriSyntaxFlags.MayHaveUserInfo |
-                                            UriSyntaxFlags.MayHavePort |
-                                            UriSyntaxFlags.MayHavePath |
-                                            UriSyntaxFlags.MayHaveQuery |
-                                            UriSyntaxFlags.MayHaveFragment |
-                                            //
-                                            UriSyntaxFlags.AllowEmptyHost |
-                                            UriSyntaxFlags.AllowUncHost |       //
-                                            UriSyntaxFlags.AllowAnInternetHost |
-                                            // UriSyntaxFlags.AllowAnyOtherHost | // V1.1 has a bug and so does not support this case
-                                            //
-                                            UriSyntaxFlags.PathIsRooted |
-                                            UriSyntaxFlags.AllowDOSPath |        //
-                                            UriSyntaxFlags.ConvertPathSlashes |  // V1 compat, it will always convert backslashes
-                                            UriSyntaxFlags.CompressPath |        // V1 compat, it will always compress path even for non hierarchical Uris
-                                            UriSyntaxFlags.AllowIdn |
-                                            UriSyntaxFlags.AllowIriParsing;
-
-        private  static readonly UriSyntaxFlags HttpSyntaxFlags =
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        //
-                                        UriSyntaxFlags.MayHaveUserInfo |
-                                        UriSyntaxFlags.MayHavePort |
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveQuery |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        //
-                                        UriSyntaxFlags.AllowUncHost |       //
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.PathIsRooted |
-                                        //
-                                        UriSyntaxFlags.ConvertPathSlashes |
-                                        UriSyntaxFlags.CompressPath |
-                                        UriSyntaxFlags.CanonicalizeAsFilePath |
-                                        (UriParser.ShouldUseLegacyV2Quirks 
-                                            ? UriSyntaxFlags.UnEscapeDotsAndSlashes : UriSyntaxFlags.None) |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-        private  const UriSyntaxFlags FtpSyntaxFlags =
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        //
-                                        UriSyntaxFlags.MayHaveUserInfo |
-                                        UriSyntaxFlags.MayHavePort |
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        //
-                                        UriSyntaxFlags.AllowUncHost |       //
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.PathIsRooted |
-                                        //
-                                        UriSyntaxFlags.ConvertPathSlashes |
-                                        UriSyntaxFlags.CompressPath |
-                                        UriSyntaxFlags.CanonicalizeAsFilePath|
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-        private  static readonly UriSyntaxFlags FileSyntaxFlags =
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        //
-                                        UriSyntaxFlags.AllowEmptyHost |
-                                        UriSyntaxFlags.AllowUncHost |
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        (UriParser.ShouldUseLegacyV2Quirks 
-                                            ? UriSyntaxFlags.None : UriSyntaxFlags.MayHaveQuery) |
-                                        //
-                                        UriSyntaxFlags.FileLikeUri |
-                                        //
-                                        UriSyntaxFlags.PathIsRooted |
-                                        UriSyntaxFlags.AllowDOSPath |
-                                        //
-                                        UriSyntaxFlags.ConvertPathSlashes |
-                                        UriSyntaxFlags.CompressPath |
-                                        UriSyntaxFlags.CanonicalizeAsFilePath |
-                                        UriSyntaxFlags.UnEscapeDotsAndSlashes |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-
-        // bad guy
-        private  const UriSyntaxFlags VsmacrosSyntaxFlags =
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        //
-                                        UriSyntaxFlags.AllowEmptyHost |
-                                        UriSyntaxFlags.AllowUncHost |
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        //
-                                        UriSyntaxFlags.FileLikeUri |
-                                        //
-                                        UriSyntaxFlags.AllowDOSPath |
-                                        UriSyntaxFlags.ConvertPathSlashes |
-                                        UriSyntaxFlags.CompressPath |
-                                        UriSyntaxFlags.CanonicalizeAsFilePath |
-                                        UriSyntaxFlags.UnEscapeDotsAndSlashes |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-        private  const UriSyntaxFlags GopherSyntaxFlags =
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        //
-                                        UriSyntaxFlags.MayHaveUserInfo |
-                                        UriSyntaxFlags.MayHavePort |
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        //
-                                        UriSyntaxFlags.AllowUncHost |       //
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.PathIsRooted |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-//                                        UriSyntaxFlags.KeepTailLWS |
-
-        //Note that NNTP and NEWS are quite different in syntax
-        private const UriSyntaxFlags NewsSyntaxFlags =
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveFragment | 
-                                        UriSyntaxFlags.AllowIriParsing;
-
-        private  const UriSyntaxFlags NntpSyntaxFlags =
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        //
-                                        UriSyntaxFlags.MayHaveUserInfo|
-                                        UriSyntaxFlags.MayHavePort |
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        //
-                                        UriSyntaxFlags.AllowUncHost |       //
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.PathIsRooted |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-
-        private const UriSyntaxFlags TelnetSyntaxFlags =
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        //
-                                        UriSyntaxFlags.MayHaveUserInfo|
-                                        UriSyntaxFlags.MayHavePort |
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        //
-                                        UriSyntaxFlags.AllowUncHost |       //
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.PathIsRooted |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-
-        private const UriSyntaxFlags LdapSyntaxFlags =
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        //
-                                        UriSyntaxFlags.AllowEmptyHost |
-                                        UriSyntaxFlags.AllowUncHost |       //
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.MayHaveUserInfo |
-                                        UriSyntaxFlags.MayHavePort |
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveQuery |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        //
-                                        UriSyntaxFlags.PathIsRooted |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-
-        private const UriSyntaxFlags MailtoSyntaxFlags =
-                                        //
-                                        UriSyntaxFlags.AllowEmptyHost |
-                                        UriSyntaxFlags.AllowUncHost |       //
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        //
-                                        UriSyntaxFlags.MayHaveUserInfo |
-                                        UriSyntaxFlags.MayHavePort |
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        UriSyntaxFlags.MayHaveQuery | //to maintain everett compat
-                                        //
-                                        UriSyntaxFlags.MailToLikeUri |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-
-        
-        private const UriSyntaxFlags NetPipeSyntaxFlags = 
-                                        UriSyntaxFlags.MustHaveAuthority |
-                                        UriSyntaxFlags.MayHavePath |
-                                        UriSyntaxFlags.MayHaveQuery |
-                                        UriSyntaxFlags.MayHaveFragment |
-                                        UriSyntaxFlags.AllowAnInternetHost |
-                                        UriSyntaxFlags.PathIsRooted |
-                                        UriSyntaxFlags.ConvertPathSlashes |
-                                        UriSyntaxFlags.CompressPath |
-                                        UriSyntaxFlags.CanonicalizeAsFilePath |
-                                        UriSyntaxFlags.UnEscapeDotsAndSlashes |
-                                        UriSyntaxFlags.AllowIdn |
-                                        UriSyntaxFlags.AllowIriParsing;
-
-    
-        private const UriSyntaxFlags NetTcpSyntaxFlags = NetPipeSyntaxFlags | UriSyntaxFlags.MayHavePort;
-
-    }
-}
+// //------------------------------------------------------------------------------
+// // <copyright file="_UriSyntax.cs" company="Microsoft">
+// //     Copyright (c) Microsoft Corporation.  All rights reserved.
+// // </copyright>
+// //------------------------------------------------------------------------------
+//
+//     //
+//     // This file utilizes partial class feature and contains
+//     // only internal implementation of UriParser type
+//     //
+//
+// namespace System {
+//
+//     using System.Collections.Generic;
+//     using System.Diagnostics;
+//     using System.Runtime.Versioning;
+//
+//     // This enum specifies the Uri syntax flags that is understood by builtin Uri parser.
+//     [Flags]
+//     internal enum UriSyntaxFlags {
+//         None                    = 0x0,
+//
+//         MustHaveAuthority       = 0x1,  // must have "//" after scheme:
+//         OptionalAuthority       = 0x2,  // used by generic parser due to unknown Uri syntax
+//         MayHaveUserInfo         = 0x4,
+//         MayHavePort             = 0x8,
+//         MayHavePath             = 0x10,
+//         MayHaveQuery            = 0x20,
+//         MayHaveFragment         = 0x40,
+//
+//         AllowEmptyHost          = 0x80,
+//         AllowUncHost            = 0x100,
+//         AllowDnsHost            = 0x200,
+//         AllowIPv4Host           = 0x400,
+//         AllowIPv6Host           = 0x800,
+//         AllowAnInternetHost     = AllowDnsHost|AllowIPv4Host|AllowIPv6Host,
+//         AllowAnyOtherHost       = 0x1000, // Relaxed authority syntax
+//
+//         FileLikeUri             = 0x2000, //Special case to allow file:\\balbla or file://\\balbla
+//         MailToLikeUri           = 0x4000, //V1 parser inheritance mailTo:AuthorityButNoSlashes
+//
+//         V1_UnknownUri           = 0x10000, // a Compatibility with V1 parser for an unknown scheme
+//         SimpleUserSyntax        = 0x20000, // It is safe to not call virtual UriParser methods
+//         BuiltInSyntax           = 0x40000, // This is a simple Uri plus it is hardcoded in the product
+//         ParserSchemeOnly        = 0x80000, // This is a Parser that does only Uri scheme parsing
+//
+//         AllowDOSPath            = 0x100000,  // will check for "x:\"
+//         PathIsRooted            = 0x200000,  // For an authority based Uri the first path char is '/'
+//         ConvertPathSlashes      = 0x400000,  // will turn '\' into '/'
+//         CompressPath            = 0x800000,  // For an authority based Uri remove/compress /./ /../ in the path
+//         CanonicalizeAsFilePath  = 0x1000000, // remove/convert sequences /.../ /x../ /x./ dangerous for a DOS path
+//         UnEscapeDotsAndSlashes  = 0x2000000, // additionally unescape dots and slashes before doing path compression
+//         AllowIdn                = 0x4000000,    // IDN host conversion allowed
+//         AllowIriParsing         = 0x10000000,   // Iri parsing. String is normalized, bidi control 
+//                                                 // characters are removed, unicode char limits are checked etc.
+//
+// //      KeepTailLWS             = 0x8000000,
+//     }
+//
+//     //
+//     // Only internal members are included here
+//     //
+//     public abstract partial class UriParser {
+//         private static readonly Dictionary<String, UriParser> m_Table;
+//         private static Dictionary<String, UriParser> m_TempTable;
+//
+//         private UriSyntaxFlags m_Flags;
+//         
+//         // Some flags (specified in c_UpdatableFlags) besides being set in the ctor, can also be set at a later
+//         // point. Such "updatable" flags can be set using SetUpdatableFlags(); if this method is called,
+//         // the value specified in the ctor is ignored (i.e. for all c_UpdatableFlags the value in m_Flags is
+//         // ignored), and the new value is used (i.e. for all c_UpdatableFlags the value in m_UpdatableFlags is used).
+//         private volatile UriSyntaxFlags m_UpdatableFlags;
+//         private volatile bool m_UpdatableFlagsUsed;
+//
+//         // The following flags can be updated at any time.
+//         private const UriSyntaxFlags c_UpdatableFlags = UriSyntaxFlags.UnEscapeDotsAndSlashes;
+//         
+//         private int m_Port;
+//         private string m_Scheme;
+//
+//         internal const int NoDefaultPort = -1;
+//         private const int c_InitialTableSize = 25;
+//
+//         // These are always available without paying hashtable lookup cost
+//         // Note: see UpdateStaticSyntaxReference()
+//         internal static UriParser HttpUri;
+//         internal static UriParser HttpsUri;
+//         internal static UriParser WsUri;
+//         internal static UriParser WssUri;
+//         internal static UriParser FtpUri;
+//         internal static UriParser FileUri;
+//         internal static UriParser GopherUri;
+//         internal static UriParser NntpUri;
+//         internal static UriParser NewsUri;
+//         internal static UriParser MailToUri;
+//         internal static UriParser UuidUri;
+//         internal static UriParser TelnetUri;
+//         internal static UriParser LdapUri;
+//         internal static UriParser NetTcpUri;
+//         internal static UriParser NetPipeUri;
+//
+//         internal static UriParser VsMacrosUri; //bad guy
+//
+//         
+//         private enum UriQuirksVersion {
+//             // V1 = 1, // RFC 1738 - Not supported
+//             V2 = 2, // RFC 2396
+//             V3 = 3, // RFC 3986, 3987
+//         }
+//
+//         // Store in a static field to allow for test manipulation and emergency workarounds via reflection.
+//         // Note this is not placed in the Uri class in order to avoid circular static dependencies.
+//         private static readonly UriQuirksVersion s_QuirksVersion = 
+//             (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5
+//                  // || BinaryCompatibility.TargetsAtLeast_Silverlight_V6
+//                  // || BinaryCompatibility.TargetsAtLeast_Phone_V8_0
+//                  ) ? UriQuirksVersion.V3 : UriQuirksVersion.V2;
+//
+//         internal static bool ShouldUseLegacyV2Quirks {
+//             get {
+//                 return s_QuirksVersion <= UriQuirksVersion.V2;
+//             }
+//         }
+//
+//         internal static bool DontEnableStrictRFC3986ReservedCharacterSets
+//         {
+//             get {
+//                 return LocalAppContextSwitches.DontEnableStrictRFC3986ReservedCharacterSets;
+//             }
+//         }
+//
+//         internal static bool DontKeepUnicodeBidiFormattingCharacters
+//         {
+//             get
+//             {
+//                 return LocalAppContextSwitches.DontKeepUnicodeBidiFormattingCharacters;
+//             }
+//         }
+//
+//         static UriParser() {
+//
+//             m_Table = new Dictionary<String, UriParser>(c_InitialTableSize);
+//             m_TempTable = new Dictionary<String, UriParser>(c_InitialTableSize);
+//
+//             //Now we will call for the instance constructors that will interrupt this static one.
+//
+//             // Below we simulate calls into FetchSyntax() but avoid using lock() and other things redundant for a .cctor
+//
+//             HttpUri   = new BuiltInUriParser("http", 80, HttpSyntaxFlags);
+//             m_Table[HttpUri.SchemeName] = HttpUri;                   //HTTP
+//
+//             HttpsUri  = new BuiltInUriParser("https", 443, HttpUri.m_Flags);
+//             m_Table[HttpsUri.SchemeName] = HttpsUri;                  //HTTPS cloned from HTTP
+//
+//             WsUri = new BuiltInUriParser("ws", 80, HttpSyntaxFlags);
+//             m_Table[WsUri.SchemeName] = WsUri;                   // WebSockets
+//
+//             WssUri = new BuiltInUriParser("wss", 443, HttpSyntaxFlags);
+//             m_Table[WssUri.SchemeName] = WssUri;                  // Secure WebSockets
+//
+//             FtpUri    = new BuiltInUriParser("ftp", 21, FtpSyntaxFlags);
+//             m_Table[FtpUri.SchemeName] = FtpUri;                    //FTP
+//
+//             FileUri   = new BuiltInUriParser("file", NoDefaultPort, FileSyntaxFlags);
+//             m_Table[FileUri.SchemeName] = FileUri;                   //FILE
+//
+//             GopherUri = new BuiltInUriParser("gopher", 70, GopherSyntaxFlags);
+//             m_Table[GopherUri.SchemeName] = GopherUri;                 //GOPHER
+//
+//             NntpUri   = new BuiltInUriParser("nntp", 119, NntpSyntaxFlags);
+//             m_Table[NntpUri.SchemeName] = NntpUri;                   //NNTP
+//
+//             NewsUri   = new BuiltInUriParser("news", NoDefaultPort, NewsSyntaxFlags);
+//             m_Table[NewsUri.SchemeName] = NewsUri;                   //NEWS
+//
+//             MailToUri = new BuiltInUriParser("mailto", 25, MailtoSyntaxFlags);
+//             m_Table[MailToUri.SchemeName] = MailToUri;                 //MAILTO
+//
+//             UuidUri   = new BuiltInUriParser("uuid", NoDefaultPort, NewsUri.m_Flags);
+//             m_Table[UuidUri.SchemeName] = UuidUri;                   //UUID cloned from NEWS
+//
+//             TelnetUri = new BuiltInUriParser("telnet", 23, TelnetSyntaxFlags);
+//             m_Table[TelnetUri.SchemeName] = TelnetUri;                 //TELNET
+//
+//             LdapUri   = new BuiltInUriParser("ldap", 389, LdapSyntaxFlags);
+//             m_Table[LdapUri.SchemeName] = LdapUri;                   //LDAP
+//
+//             NetTcpUri   = new BuiltInUriParser("net.tcp", 808, NetTcpSyntaxFlags);
+//             m_Table[NetTcpUri.SchemeName] = NetTcpUri;   
+//
+//             NetPipeUri   = new BuiltInUriParser("net.pipe", NoDefaultPort, NetPipeSyntaxFlags);
+//             m_Table[NetPipeUri.SchemeName] = NetPipeUri;   
+//
+//             VsMacrosUri = new BuiltInUriParser("vsmacros", NoDefaultPort, VsmacrosSyntaxFlags);
+//             m_Table[VsMacrosUri.SchemeName] = VsMacrosUri;               //VSMACROS
+//
+//         }
+//         //
+//         private class BuiltInUriParser: UriParser
+//         {
+//             //
+//             // All BuiltIn parsers use that ctor. They are marked with "simple" and "built-in" flags
+//             //
+//             internal BuiltInUriParser(string lwrCaseScheme, int defaultPort, UriSyntaxFlags syntaxFlags)
+//                 : base ((syntaxFlags | UriSyntaxFlags.SimpleUserSyntax | UriSyntaxFlags.BuiltInSyntax))
+//             {
+//                 m_Scheme = lwrCaseScheme;
+//                 m_Port   = defaultPort;
+//             }
+//         }
+//         //
+//         internal UriSyntaxFlags Flags {
+//             get {
+//                 return m_Flags;
+//             }
+//         }
+//         //
+//         internal bool NotAny(UriSyntaxFlags flags)
+//         {
+//             // Return true if none of the flags specified in 'flags' are set.
+//             return IsFullMatch(flags, UriSyntaxFlags.None);
+//         }
+//         //
+//         internal bool InFact(UriSyntaxFlags flags)
+//         {
+//             // Return true if at least one of the flags in 'flags' is set.
+//             return !IsFullMatch(flags, UriSyntaxFlags.None);
+//         }
+//         //
+//         internal bool IsAllSet(UriSyntaxFlags flags)
+//         {
+//             // Return true if all flags in 'flags' are set.
+//             return IsFullMatch(flags, flags);
+//         }
+//
+//         private bool IsFullMatch(UriSyntaxFlags flags, UriSyntaxFlags expected)
+//         {
+//             // Return true, if masking the current set of flags with 'flags' equals 'expected'.
+//             // Definition 'current set of flags': 
+//             // a) if updatable flags were never set: m_Flags
+//             // b) if updatable flags were set: set union between all flags in m_Flags which are not updatable
+//             //    (i.e. not part of c_UpdatableFlags) and all flags in m_UpdatableFlags
+//
+//             UriSyntaxFlags mergedFlags;
+//
+//             // if none of the flags in 'flags' is an updatable flag, we ignore m_UpdatableFlags
+//             if (((flags & c_UpdatableFlags) == 0) || !m_UpdatableFlagsUsed)
+//             {
+//                 mergedFlags = m_Flags;
+//             }
+//             else
+//             {
+//                 // mask m_Flags to only use the flags not in c_UpdatableFlags
+//                 mergedFlags = (m_Flags & (~c_UpdatableFlags)) | m_UpdatableFlags;
+//             }
+//
+//             return (mergedFlags & flags) == expected;
+//         }
+//
+//         //
+//         // Internal .ctor, any ctor eventually goes through this one
+//         //
+//         internal UriParser(UriSyntaxFlags flags)
+//         {
+//             m_Flags = flags;
+//             m_Scheme = string.Empty;
+//         }
+//         //
+//         private static void FetchSyntax(UriParser syntax, string lwrCaseSchemeName, int defaultPort)
+//         {
+//             if (syntax.SchemeName.Length != 0)
+//                 throw new InvalidOperationException(SR.GetString(SR.net_uri_NeedFreshParser, syntax.SchemeName));
+//
+//             lock (m_Table)
+//             {
+//                 syntax.m_Flags &= ~UriSyntaxFlags.V1_UnknownUri;
+//                 UriParser oldSyntax = null;
+//                 m_Table.TryGetValue(lwrCaseSchemeName, out oldSyntax);
+//                 if (oldSyntax != null)
+//                     throw new InvalidOperationException(SR.GetString(SR.net_uri_AlreadyRegistered, oldSyntax.SchemeName));
+//                 
+//                 m_TempTable.TryGetValue(syntax.SchemeName, out oldSyntax);
+//                 if (oldSyntax != null)
+//                 {
+//                     // optimization on schemeName, will try to keep the first reference
+//                     lwrCaseSchemeName = oldSyntax.m_Scheme;
+//                     m_TempTable.Remove(lwrCaseSchemeName);
+//                 }
+//
+//                 syntax.OnRegister(lwrCaseSchemeName, defaultPort);
+//                 syntax.m_Scheme = lwrCaseSchemeName;
+//                 syntax.CheckSetIsSimpleFlag();
+//                 syntax.m_Port = defaultPort;
+//
+//                 m_Table[syntax.SchemeName] = syntax;
+//             }
+//         }
+//         //
+//         private const int c_MaxCapacity = 512;
+//         //schemeStr must be in lower case!
+//         internal static UriParser FindOrFetchAsUnknownV1Syntax(string lwrCaseScheme) {
+//
+//             // check may be other thread just added one
+//             UriParser syntax = null;
+//             m_Table.TryGetValue(lwrCaseScheme, out syntax);
+//             if (syntax != null) {
+//                 return syntax;
+//             }
+//             m_TempTable.TryGetValue(lwrCaseScheme, out syntax);
+//             if (syntax != null) {
+//                 return syntax;
+//             }
+//             lock (m_Table) {
+//                 // This is a bit paranoid but let's prevent static table growing infinitly
+//                 if (m_TempTable.Count >= c_MaxCapacity) {
+//                     m_TempTable = new Dictionary<String, UriParser>(c_InitialTableSize);
+//                 }
+//                 syntax = new BuiltInUriParser(lwrCaseScheme, NoDefaultPort, UnknownV1SyntaxFlags);
+//                 m_TempTable[lwrCaseScheme] = syntax;
+//                 return syntax;
+//             }
+//         }
+//         //
+//         internal static UriParser GetSyntax(string lwrCaseScheme) {
+//             UriParser ret = null;
+//             m_Table.TryGetValue(lwrCaseScheme, out ret);
+//             if (ret == null) {
+//                 m_TempTable.TryGetValue(lwrCaseScheme, out ret);
+//             }
+//             return ret;
+//         }
+//         //
+//         // Builtin and User Simple syntaxes do not need custom validation/parsing (i.e. virtual method calls),
+//         //
+//         internal bool IsSimple
+//         {
+//             get {
+//                 return InFact(UriSyntaxFlags.SimpleUserSyntax);
+//             }
+//         }
+//         //
+//         internal void CheckSetIsSimpleFlag()
+//         {
+//             Type type  = this.GetType();
+//
+//             if (    type == typeof(GenericUriParser)     
+//                 ||  type == typeof(HttpStyleUriParser)   
+//                 ||  type == typeof(FtpStyleUriParser)   
+//                 ||  type == typeof(FileStyleUriParser)   
+//                 ||  type == typeof(NewsStyleUriParser)   
+//                 ||  type == typeof(GopherStyleUriParser) 
+//                 ||  type == typeof(NetPipeStyleUriParser) 
+//                 ||  type == typeof(NetTcpStyleUriParser) 
+//                 ||  type == typeof(LdapStyleUriParser)
+//                 )
+//             {
+//                 m_Flags |= UriSyntaxFlags.SimpleUserSyntax;
+//             }
+//         }
+//
+//         //
+//         // This method is used to update flags. The scenario where this is needed is when the user specifies
+//         // flags in the config file. The config file is read after UriParser instances were created.
+//         //
+//         internal void SetUpdatableFlags(UriSyntaxFlags flags) {
+//
+//             Debug.Assert(!m_UpdatableFlagsUsed, 
+//                 "SetUpdatableFlags() already called. It can only be called once per parser.");
+//             Debug.Assert((flags & (~c_UpdatableFlags)) == 0, "Only updatable flags can be set.");
+//
+//             // No locks necessary. Reordering won't happen due to volatile.
+//             m_UpdatableFlags = flags;
+//             m_UpdatableFlagsUsed = true;
+//         }
+//
+//         //
+//         // These are simple internal wrappers that will call virtual protected methods
+//         // (to avoid "protected internal" siganures in the public docs)
+//         //
+//         internal UriParser InternalOnNewUri()
+//         {
+//             UriParser effectiveParser = OnNewUri();
+//             if ((object)this != (object)effectiveParser)
+//             {
+//                 effectiveParser.m_Scheme = m_Scheme;
+//                 effectiveParser.m_Port   = m_Port;
+//                 effectiveParser.m_Flags  = m_Flags;
+//             }
+//             return effectiveParser;
+//         }
+//
+//         //
+//         internal void InternalValidate(Uri thisUri, out UriFormatException parsingError)
+//         {
+//             InitializeAndValidate(thisUri, out parsingError);
+//         }
+//
+//         //
+//         internal string InternalResolve(Uri thisBaseUri, Uri uriLink, out UriFormatException parsingError)
+//         {
+//             return Resolve(thisBaseUri, uriLink, out parsingError);
+//         }
+//
+//         //
+//         internal bool InternalIsBaseOf(Uri thisBaseUri, Uri uriLink)
+//         {
+//             return IsBaseOf(thisBaseUri, uriLink);
+//         }
+//
+//         //
+//         internal string InternalGetComponents(Uri thisUri, UriComponents uriComponents, UriFormat uriFormat)
+//         {
+//             return GetComponents(thisUri, uriComponents, uriFormat);
+//         }
+//
+//         //
+//         internal bool InternalIsWellFormedOriginalString(Uri thisUri)
+//         {
+//             return IsWellFormedOriginalString(thisUri);
+//         }
+//
+//         //
+//         // Various Uri scheme syntax flags
+//         //
+//         private const UriSyntaxFlags UnknownV1SyntaxFlags =
+//                                             UriSyntaxFlags.V1_UnknownUri | // This flag must be always set here
+//                                             UriSyntaxFlags.OptionalAuthority |
+//                                             //
+//                                             UriSyntaxFlags.MayHaveUserInfo |
+//                                             UriSyntaxFlags.MayHavePort |
+//                                             UriSyntaxFlags.MayHavePath |
+//                                             UriSyntaxFlags.MayHaveQuery |
+//                                             UriSyntaxFlags.MayHaveFragment |
+//                                             //
+//                                             UriSyntaxFlags.AllowEmptyHost |
+//                                             UriSyntaxFlags.AllowUncHost |       //
+//                                             UriSyntaxFlags.AllowAnInternetHost |
+//                                             // UriSyntaxFlags.AllowAnyOtherHost | // V1.1 has a bug and so does not support this case
+//                                             //
+//                                             UriSyntaxFlags.PathIsRooted |
+//                                             UriSyntaxFlags.AllowDOSPath |        //
+//                                             UriSyntaxFlags.ConvertPathSlashes |  // V1 compat, it will always convert backslashes
+//                                             UriSyntaxFlags.CompressPath |        // V1 compat, it will always compress path even for non hierarchical Uris
+//                                             UriSyntaxFlags.AllowIdn |
+//                                             UriSyntaxFlags.AllowIriParsing;
+//
+//         private  static readonly UriSyntaxFlags HttpSyntaxFlags =
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         //
+//                                         UriSyntaxFlags.MayHaveUserInfo |
+//                                         UriSyntaxFlags.MayHavePort |
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveQuery |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         //
+//                                         UriSyntaxFlags.AllowUncHost |       //
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.PathIsRooted |
+//                                         //
+//                                         UriSyntaxFlags.ConvertPathSlashes |
+//                                         UriSyntaxFlags.CompressPath |
+//                                         UriSyntaxFlags.CanonicalizeAsFilePath |
+//                                         (UriParser.ShouldUseLegacyV2Quirks 
+//                                             ? UriSyntaxFlags.UnEscapeDotsAndSlashes : UriSyntaxFlags.None) |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//         private  const UriSyntaxFlags FtpSyntaxFlags =
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         //
+//                                         UriSyntaxFlags.MayHaveUserInfo |
+//                                         UriSyntaxFlags.MayHavePort |
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         //
+//                                         UriSyntaxFlags.AllowUncHost |       //
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.PathIsRooted |
+//                                         //
+//                                         UriSyntaxFlags.ConvertPathSlashes |
+//                                         UriSyntaxFlags.CompressPath |
+//                                         UriSyntaxFlags.CanonicalizeAsFilePath|
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//         private  static readonly UriSyntaxFlags FileSyntaxFlags =
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         //
+//                                         UriSyntaxFlags.AllowEmptyHost |
+//                                         UriSyntaxFlags.AllowUncHost |
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         (UriParser.ShouldUseLegacyV2Quirks 
+//                                             ? UriSyntaxFlags.None : UriSyntaxFlags.MayHaveQuery) |
+//                                         //
+//                                         UriSyntaxFlags.FileLikeUri |
+//                                         //
+//                                         UriSyntaxFlags.PathIsRooted |
+//                                         UriSyntaxFlags.AllowDOSPath |
+//                                         //
+//                                         UriSyntaxFlags.ConvertPathSlashes |
+//                                         UriSyntaxFlags.CompressPath |
+//                                         UriSyntaxFlags.CanonicalizeAsFilePath |
+//                                         UriSyntaxFlags.UnEscapeDotsAndSlashes |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//
+//         // bad guy
+//         private  const UriSyntaxFlags VsmacrosSyntaxFlags =
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         //
+//                                         UriSyntaxFlags.AllowEmptyHost |
+//                                         UriSyntaxFlags.AllowUncHost |
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         //
+//                                         UriSyntaxFlags.FileLikeUri |
+//                                         //
+//                                         UriSyntaxFlags.AllowDOSPath |
+//                                         UriSyntaxFlags.ConvertPathSlashes |
+//                                         UriSyntaxFlags.CompressPath |
+//                                         UriSyntaxFlags.CanonicalizeAsFilePath |
+//                                         UriSyntaxFlags.UnEscapeDotsAndSlashes |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//         private  const UriSyntaxFlags GopherSyntaxFlags =
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         //
+//                                         UriSyntaxFlags.MayHaveUserInfo |
+//                                         UriSyntaxFlags.MayHavePort |
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         //
+//                                         UriSyntaxFlags.AllowUncHost |       //
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.PathIsRooted |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+// //                                        UriSyntaxFlags.KeepTailLWS |
+//
+//         //Note that NNTP and NEWS are quite different in syntax
+//         private const UriSyntaxFlags NewsSyntaxFlags =
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveFragment | 
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//         private  const UriSyntaxFlags NntpSyntaxFlags =
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         //
+//                                         UriSyntaxFlags.MayHaveUserInfo|
+//                                         UriSyntaxFlags.MayHavePort |
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         //
+//                                         UriSyntaxFlags.AllowUncHost |       //
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.PathIsRooted |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//
+//         private const UriSyntaxFlags TelnetSyntaxFlags =
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         //
+//                                         UriSyntaxFlags.MayHaveUserInfo|
+//                                         UriSyntaxFlags.MayHavePort |
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         //
+//                                         UriSyntaxFlags.AllowUncHost |       //
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.PathIsRooted |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//
+//         private const UriSyntaxFlags LdapSyntaxFlags =
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         //
+//                                         UriSyntaxFlags.AllowEmptyHost |
+//                                         UriSyntaxFlags.AllowUncHost |       //
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.MayHaveUserInfo |
+//                                         UriSyntaxFlags.MayHavePort |
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveQuery |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         //
+//                                         UriSyntaxFlags.PathIsRooted |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//
+//         private const UriSyntaxFlags MailtoSyntaxFlags =
+//                                         //
+//                                         UriSyntaxFlags.AllowEmptyHost |
+//                                         UriSyntaxFlags.AllowUncHost |       //
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         //
+//                                         UriSyntaxFlags.MayHaveUserInfo |
+//                                         UriSyntaxFlags.MayHavePort |
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         UriSyntaxFlags.MayHaveQuery | //to maintain everett compat
+//                                         //
+//                                         UriSyntaxFlags.MailToLikeUri |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//
+//         
+//         private const UriSyntaxFlags NetPipeSyntaxFlags = 
+//                                         UriSyntaxFlags.MustHaveAuthority |
+//                                         UriSyntaxFlags.MayHavePath |
+//                                         UriSyntaxFlags.MayHaveQuery |
+//                                         UriSyntaxFlags.MayHaveFragment |
+//                                         UriSyntaxFlags.AllowAnInternetHost |
+//                                         UriSyntaxFlags.PathIsRooted |
+//                                         UriSyntaxFlags.ConvertPathSlashes |
+//                                         UriSyntaxFlags.CompressPath |
+//                                         UriSyntaxFlags.CanonicalizeAsFilePath |
+//                                         UriSyntaxFlags.UnEscapeDotsAndSlashes |
+//                                         UriSyntaxFlags.AllowIdn |
+//                                         UriSyntaxFlags.AllowIriParsing;
+//
+//     
+//         private const UriSyntaxFlags NetTcpSyntaxFlags = NetPipeSyntaxFlags | UriSyntaxFlags.MayHavePort;
+//
+//     }
+// }
