diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ccdf041
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Microsoft Corporation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy 
+of this software and associated documentation files (the "Software"), to deal 
+in the Software without restriction, including without limitation the rights 
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+copies of the Software, and to permit persons to whom the Software is 
+furnished to do so, subject to the following conditions: 
+
+The above copyright notice and this permission notice shall be included in all 
+copies or substantial portions of the Software. 
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+SOFTWARE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..c2157c4
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,19 @@
+name: ".NET Framework Reference Source"
+description:
+    "Source from the Microsoft .NET Reference "
+    "Source that represent a subset of the "
+	".NET Framework"
+
+third_party {
+  url {
+    type: HOMEPAGE
+    value: "https://referencesource.microsoft.com/"
+  }
+  url {
+    type: GIT
+    value: "https://github.com/microsoft/referencesource.git"
+  }
+  version: "4.6.2"
+  last_upgrade_date { year: 2023 month: 03 day: 29 }
+  license_type: NOTICE
+}
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..60df063
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,12 @@
+set noparent
+
+adamws@google.com
+bcairns@google.com
+gregdenton@google.com
+hugheshilton@google.com
+ianfisk@google.com
+igorveli@google.com
+joshuta@google.com
+kellerc@google.com
+lhumphries@google.com
+tryland@google.com
\ No newline at end of file
diff --git a/System/net/System/URI.cs b/System/net/System/URI.cs
new file mode 100644
index 0000000..e264a1f
--- /dev/null
+++ b/System/net/System/URI.cs
@@ -0,0 +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;
+//            }
+//#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
+
diff --git a/System/net/System/UriExt.cs b/System/net/System/UriExt.cs
new file mode 100644
index 0000000..b9e018e
--- /dev/null
+++ b/System/net/System/UriExt.cs
@@ -0,0 +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;
+            }
+        }
+    }
+}
diff --git a/System/net/System/UriHelper.cs b/System/net/System/UriHelper.cs
new file mode 100644
index 0000000..f81a765
--- /dev/null
+++ b/System/net/System/UriHelper.cs
@@ -0,0 +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);
+        }
+    }
+}
diff --git a/System/net/System/_UriSyntax.cs b/System/net/System/_UriSyntax.cs
new file mode 100644
index 0000000..07c34d3
--- /dev/null
+++ b/System/net/System/_UriSyntax.cs
@@ -0,0 +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;
+
+    }
+}
