2010-06-01 Marek Habersack <mhabersack@novell.com>
authorMarek Habersack <grendel@twistedcode.net>
Tue, 1 Jun 2010 19:39:19 +0000 (19:39 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Tue, 1 Jun 2010 19:39:19 +0000 (19:39 -0000)
* HttpUtility.cs: moved chunks of code to the new
System.Web.Util.HttpEncoder class.

* HttpResponseHeader.cs: encode header names and values using
HttpEncoder.

* HttpRequest.cs: added internal method Validate, to validate the
request in 4.0 profile.

* HttpHeaderCollection.cs: added. A helper class to encode header
names/values on add.

* HttpApplication.cs: Pipeline () validates request by calling
HttpRequest.Validate in the 4.0 profile.

2010-06-01  Marek Habersack  <mhabersack@novell.com>

* HttpEncoder.cs: added. A 4.0 type but also used in 2.0 profile,
internally.

2010-06-01  Marek Habersack  <mhabersack@novell.com>

* HttpRuntimeSection.cs: added 4.0 properties
MaxQueryLengthString, MaxUrlLength, EncoderType and
RelaxedUrlToFileSystemMapping.

svn path=/trunk/mcs/; revision=158300

16 files changed:
mcs/class/System.Web/System.Web.Configuration_2.0/ChangeLog
mcs/class/System.Web/System.Web.Configuration_2.0/HttpRuntimeSection.cs
mcs/class/System.Web/System.Web.Util/ChangeLog
mcs/class/System.Web/System.Web.Util/HttpEncoder.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web.dll.sources
mcs/class/System.Web/System.Web/ChangeLog
mcs/class/System.Web/System.Web/HttpApplication.cs
mcs/class/System.Web/System.Web/HttpHeaderCollection.cs [new file with mode: 0644]
mcs/class/System.Web/System.Web/HttpRequest.cs
mcs/class/System.Web/System.Web/HttpResponse.cs
mcs/class/System.Web/System.Web/HttpResponseHeader.cs
mcs/class/System.Web/System.Web/HttpUtility.cs
mcs/class/System.Web/System.Web_test.dll.sources
mcs/class/System.Web/Test/System.Web.Util/HttpEncoderTest.cs [new file with mode: 0644]
mcs/class/System.Web/Test/System.Web/HttpUtilityTest.cs
mcs/class/System.Web/Test/standalone/RegisterBuildProvider/Makefile

index 23ad6045d80f914c1358508e56ac98199b578cc8..9b904b9da32fd3bc6e26b3254084e9d9ee661a40 100644 (file)
@@ -1,3 +1,9 @@
+2010-06-01  Marek Habersack  <mhabersack@novell.com>
+
+       * HttpRuntimeSection.cs: added 4.0 properties
+       MaxQueryLengthString, MaxUrlLength, EncoderType and
+       RelaxedUrlToFileSystemMapping.
+
 2010-05-17  Marek Habersack  <mhabersack@novell.com>
 
        * BuildProvider.cs: made the Extension property case-insensitive
index af3d4ced00f4786f0ea1e46711340668d32d5d03..361850d3c3cbed5939bf11a6711a1948c07be2d1 100644 (file)
@@ -60,6 +60,10 @@ namespace System.Web.Configuration
                static ConfigurationProperty requestPathInvalidCharactersProp;
                static ConfigurationProperty requestValidationTypeProp;
                static ConfigurationProperty requestValidationModeProp;
+               static ConfigurationProperty maxQueryStringLengthProp;
+               static ConfigurationProperty maxUrlLengthProp;
+               static ConfigurationProperty encoderTypeProp;
+               static ConfigurationProperty relaxedUrlToFileSystemMappingProp;
 #endif
                static ConfigurationPropertyCollection properties;
 
@@ -123,6 +127,19 @@ namespace System.Web.Configuration
                                                                               PropertyHelper.VersionConverter,
                                                                               PropertyHelper.DefaultValidator,
                                                                               ConfigurationPropertyOptions.None);
+                       maxQueryStringLengthProp = new ConfigurationProperty ("maxQueryStringLength", typeof (int), 2048,
+                                                                             TypeDescriptor.GetConverter (typeof (int)),
+                                                                             PropertyHelper.IntFromZeroToMaxValidator,
+                                                                             ConfigurationPropertyOptions.None);
+                       maxUrlLengthProp = new ConfigurationProperty ("maxUrlLength", typeof (int), 260,
+                                                                     TypeDescriptor.GetConverter (typeof (int)),
+                                                                     PropertyHelper.IntFromZeroToMaxValidator,
+                                                                     ConfigurationPropertyOptions.None);
+                       encoderTypeProp = new ConfigurationProperty ("encoderType", typeof (string), "System.Web.Util.HttpEncoder",
+                                                                    TypeDescriptor.GetConverter (typeof (string)),
+                                                                    PropertyHelper.NonEmptyStringValidator,
+                                                                    ConfigurationPropertyOptions.None);
+                       relaxedUrlToFileSystemMappingProp = new ConfigurationProperty ("relaxedUrlToFileSystemMapping", typeof (bool), false);
 #endif
                        
                        properties = new ConfigurationPropertyCollection();
@@ -148,6 +165,10 @@ namespace System.Web.Configuration
                        properties.Add (requestPathInvalidCharactersProp);
                        properties.Add (requestValidationTypeProp);
                        properties.Add (requestValidationModeProp);
+                       properties.Add (maxQueryStringLengthProp);
+                       properties.Add (maxUrlLengthProp);
+                       properties.Add (encoderTypeProp);
+                       properties.Add (relaxedUrlToFileSystemMappingProp);
 #endif
                }
 
@@ -282,7 +303,7 @@ namespace System.Web.Configuration
                }
 
                [ConfigurationProperty ("requestValidationType", DefaultValue = "System.Web.Util.RequestValidator")]
-               [StringValidatorAttribute(MinLength = 1)]
+               [StringValidator (MinLength = 1)]
                public string RequestValidationType {
                        get { return (string) base [requestValidationTypeProp]; }
                        set { base [requestValidationTypeProp] = value; }
@@ -294,6 +315,33 @@ namespace System.Web.Configuration
                        get { return (Version) base [requestValidationModeProp]; }
                        set { base [requestValidationModeProp] = value; }
                }
+
+               [IntegerValidator (MinValue = 0)]
+               [ConfigurationProperty ("maxQueryStringLength", DefaultValue = "2048")]
+               public int MaxQueryStringLength {
+                       get { return (int) base [maxQueryStringLengthProp]; }
+                       set { base [maxQueryStringLengthProp] = value; }
+               }
+
+               [IntegerValidator (MinValue = 0)]
+               [ConfigurationProperty ("maxUrlLength", DefaultValue = "260")]
+               public int MaxUrlLength {
+                       get { return (int) base [maxUrlLengthProp]; }
+                       set { base [maxUrlLengthProp] = value; }
+               }
+
+               [StringValidator (MinLength = 1)]
+               [ConfigurationProperty ("encoderType", DefaultValue = "System.Web.Util.HttpEncoder")]
+               public string EncoderType {
+                       get { return (string) base [encoderTypeProp]; }
+                       set { base [encoderTypeProp] = value; }
+               }
+
+               [ConfigurationProperty ("relaxedUrlToFileSystemMapping", DefaultValue = "False")]
+               public bool RelaxedUrlToFileSystemMapping {
+                       get { return (bool) base [relaxedUrlToFileSystemMappingProp]; }
+                       set { base [relaxedUrlToFileSystemMappingProp] = value; }
+               }
 #endif
                protected override ConfigurationPropertyCollection Properties {
                        get { return properties; }
index 8ce4708f209f2304d5652627468cd2ed1db8e181..f319d8eb85fab264abaab475aa4096dc23450e14 100644 (file)
@@ -1,3 +1,8 @@
+2010-06-01  Marek Habersack  <mhabersack@novell.com>
+
+       * HttpEncoder.cs: added. A 4.0 type but also used in 2.0 profile,
+       internally.
+
 2010-03-06  Marek Habersack  <mhabersack@novell.com>
 
        * RequestValidator.cs: added
diff --git a/mcs/class/System.Web/System.Web.Util/HttpEncoder.cs b/mcs/class/System.Web/System.Web.Util/HttpEncoder.cs
new file mode 100644 (file)
index 0000000..7f41f0c
--- /dev/null
@@ -0,0 +1,855 @@
+//
+// Authors:
+//   Patrik Torstensson (Patrik.Torstensson@labs2.com)
+//   Wictor Wilén (decode/encode functions) (wictor@ibizkit.se)
+//   Tim Coleman (tim@timcoleman.com)
+//   Gonzalo Paniagua Javier (gonzalo@ximian.com)
+
+//   Marek Habersack <mhabersack@novell.com>
+//
+// (C) 2005-2010 Novell, Inc (http://novell.com/)
+//
+
+//
+// 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.
+//
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Text;
+using System.Web.Configuration;
+
+namespace System.Web.Util
+{
+#if NET_4_0
+       public
+#endif
+       class HttpEncoder
+       {
+               static char [] hexChars = "0123456789abcdef".ToCharArray ();
+               static object entitiesLock = new object ();
+               static SortedDictionary <string, char> entities;
+#if NET_4_0
+               static Lazy <HttpEncoder> defaultEncoder;
+               static Lazy <HttpEncoder> currentEncoderLazy;
+#else
+               static HttpEncoder defaultEncoder;
+#endif
+               static HttpEncoder currentEncoder;
+
+               static IDictionary <string, char> Entities {
+                       get {
+                               lock (entitiesLock) {
+                                       if (entities == null)
+                                               InitEntities ();
+
+                                       return entities;
+                               }
+                       }
+               }
+               
+               public static HttpEncoder Current {
+                       get {
+#if NET_4_0
+                               if (currentEncoder == null)
+                                       currentEncoder = currentEncoderLazy.Value;
+#endif
+                               return currentEncoder;
+                       }
+#if NET_4_0
+                       set {
+                               if (value == null)
+                                       throw new ArgumentNullException ("value");
+                               currentEncoder = value;
+                       }
+#endif
+               }
+
+               public static HttpEncoder Default {
+                       get {
+#if NET_4_0
+                               return defaultEncoder.Value;
+#else
+                               return defaultEncoder;
+#endif
+                       }
+               }
+
+               static HttpEncoder ()
+               {
+#if NET_4_0
+                       defaultEncoder = new Lazy <HttpEncoder> (() => new HttpEncoder ());
+                       currentEncoderLazy = new Lazy <HttpEncoder> (new Func <HttpEncoder> (GetCustomEncoderFromConfig));
+#else
+                       defaultEncoder = new HttpEncoder ();
+                       currentEncoder = defaultEncoder;
+#endif
+               }
+               
+               public HttpEncoder ()
+               {
+               }
+#if NET_4_0    
+               protected internal virtual
+#else
+               internal static
+#endif
+               void HeaderNameValueEncode (string headerName, string headerValue, out string encodedHeaderName, out string encodedHeaderValue)
+               {
+                       if (String.IsNullOrEmpty (headerName))
+                               encodedHeaderName = headerName;
+                       else
+                               encodedHeaderName = EncodeHeaderString (headerName);
+
+                       if (String.IsNullOrEmpty (headerValue))
+                               encodedHeaderValue = headerValue;
+                       else
+                               encodedHeaderValue = EncodeHeaderString (headerValue);
+               }
+
+               static void StringBuilderAppend (string s, ref StringBuilder sb)
+               {
+                       if (sb == null)
+                               sb = new StringBuilder (s);
+                       else
+                               sb.Append (s);
+               }
+               
+               static string EncodeHeaderString (string input)
+               {
+                       StringBuilder sb = null;
+                       char ch;
+                       
+                       for (int i = 0; i < input.Length; i++) {
+                               ch = input [i];
+
+                               if ((ch < 32 && ch != 9) || ch == 127)
+                                       StringBuilderAppend (String.Format ("%{0:x2}", (int)ch), ref sb);
+                       }
+
+                       if (sb != null)
+                               return sb.ToString ();
+
+                       return input;
+               }
+#if NET_4_0            
+               protected internal virtual void HtmlAttributeEncode (string value, TextWriter output)
+               {
+
+                       if (output == null)
+                               throw new ArgumentNullException ("output");
+
+                       if (String.IsNullOrEmpty (value))
+                               return;
+
+                       output.Write (HtmlAttributeEncode (value));
+               }
+
+               protected internal virtual void HtmlDecode (string value, TextWriter output)
+               {
+                       if (output == null)
+                               throw new ArgumentNullException ("output");
+
+                       output.Write (HtmlDecode (value));
+               }
+
+               protected internal virtual void HtmlEncode (string value, TextWriter output)
+               {
+                       if (output == null)
+                               throw new ArgumentNullException ("output");
+
+                       output.Write (HtmlEncode (value));
+               }
+
+               protected internal virtual byte[] UrlEncode (byte[] bytes, int offset, int count)
+               {
+                       return UrlEncodeToBytes (bytes, offset, count);
+               }
+
+               static HttpEncoder GetCustomEncoderFromConfig ()
+               {
+                       var cfg = WebConfigurationManager.GetSection ("system.web/httpRuntime") as HttpRuntimeSection;
+                       string typeName = cfg.EncoderType;
+
+                       if (String.Compare (typeName, "System.Web.Util.HttpEncoder", StringComparison.OrdinalIgnoreCase) == 0)
+                               return Default;
+                       
+                       Type t = Type.GetType (typeName, false);
+                       if (t == null)
+                               throw new ConfigurationErrorsException (String.Format ("Could not load type '{0}'.", typeName));
+                       
+                       if (!typeof (HttpEncoder).IsAssignableFrom (t))
+                               throw new ConfigurationErrorsException (
+                                       String.Format ("'{0}' is not allowed here because it does not extend class 'System.Web.Util.HttpEncoder'.", typeName)
+                               );
+
+                       return Activator.CreateInstance (t, false) as HttpEncoder;
+               }
+#endif
+#if NET_4_0
+               protected internal virtual
+#else
+               internal static
+#endif
+               string UrlPathEncode (string value)
+               {
+                       if (String.IsNullOrEmpty (value))
+                               return value;
+
+                       MemoryStream result = new MemoryStream ();
+                       int length = value.Length;
+                       for (int i = 0; i < length; i++)
+                               UrlPathEncodeChar (value [i], result);
+                       
+                       return Encoding.ASCII.GetString (result.ToArray ());
+               }
+               
+               internal static byte[] UrlEncodeToBytes (byte[] bytes, int offset, int count)
+               {
+                       if (bytes == null)
+                               throw new ArgumentNullException ("bytes");
+                       
+                       int blen = bytes.Length;
+                       if (blen == 0)
+                               return new byte [0];
+                       
+                       if (offset < 0 || offset >= blen)
+                               throw new ArgumentOutOfRangeException("offset");
+
+                       if (count < 0 || count > blen - offset)
+                               throw new ArgumentOutOfRangeException("count");
+
+                       MemoryStream result = new MemoryStream (count);
+                       int end = offset + count;
+                       for (int i = offset; i < end; i++)
+                               UrlEncodeChar ((char)bytes [i], result, false);
+
+                       return result.ToArray();
+               }
+               
+               internal static string HtmlEncode (string s) 
+               {
+                       if (s == null)
+                               return null;
+
+                       if (s.Length == 0)
+                               return String.Empty;
+                       
+                       bool needEncode = false;
+                       for (int i = 0; i < s.Length; i++) {
+                               char c = s [i];
+                               if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159
+#if NET_4_0
+                                   || c == '\''
+#endif
+                               ) {
+                                       needEncode = true;
+                                       break;
+                               }
+                       }
+
+                       if (!needEncode)
+                               return s;
+
+                       StringBuilder output = new StringBuilder ();
+                       char ch;
+                       int len = s.Length;
+                       
+                       for (int i = 0; i < len; i++) {
+                               switch (s [i]) {
+                                       case '&' :
+                                               output.Append ("&amp;");
+                                               break;
+                                       case '>' : 
+                                               output.Append ("&gt;");
+                                               break;
+                                       case '<' :
+                                               output.Append ("&lt;");
+                                               break;
+                                       case '"' :
+                                               output.Append ("&quot;");
+                                               break;
+#if NET_4_0
+                                       case '\'':
+                                               output.Append ("&#39;");
+                                               break;
+#endif
+                                       case '\uff1c':
+                                               output.Append ("&#65308;");
+                                               break;
+
+                                       case '\uff1e':
+                                               output.Append ("&#65310;");
+                                               break;
+                                               
+                                       default:
+                                               ch = s [i];
+                                               if (ch > 159 && ch < 256) {
+                                                       output.Append ("&#");
+                                                       output.Append (((int) ch).ToString (Helpers.InvariantCulture));
+                                                       output.Append (";");
+                                               } else
+                                                       output.Append (ch);
+                                               break;
+                               }       
+                       }
+                       
+                       return output.ToString ();                      
+               }
+               
+               internal static string HtmlAttributeEncode (string s) 
+               {
+#if NET_4_0
+                       if (String.IsNullOrEmpty (s))
+                               return String.Empty;
+#else
+                       if (s == null) 
+                               return null;
+                       
+                       if (s.Length == 0)
+                               return String.Empty;
+#endif                 
+                       bool needEncode = false;
+                       for (int i = 0; i < s.Length; i++) {
+                               char c = s [i];
+                               if (c == '&' || c == '"' || c == '<'
+#if NET_4_0
+                                   || c == '\''
+#endif
+                               ) {
+                                       needEncode = true;
+                                       break;
+                               }
+                       }
+
+                       if (!needEncode)
+                               return s;
+
+                       StringBuilder output = new StringBuilder ();
+                       int len = s.Length;
+                       for (int i = 0; i < len; i++)
+                               switch (s [i]) {
+                               case '&' : 
+                                       output.Append ("&amp;");
+                                       break;
+                               case '"' :
+                                       output.Append ("&quot;");
+                                       break;
+                               case '<':
+                                       output.Append ("&lt;");
+                                       break;
+#if NET_4_0
+                               case '\'':
+                                       output.Append ("&#39;");
+                                       break;
+#endif
+                               default:
+                                       output.Append (s [i]);
+                                       break;
+                               }
+       
+                       return output.ToString();
+               }
+               
+               internal static string HtmlDecode (string s)
+               {
+                       if (s == null)
+                               return null;
+
+                       if (s.Length == 0)
+                               return String.Empty;
+                       
+                       if (s.IndexOf ('&') == -1)
+                               return s;
+#if NET_4_0
+                       StringBuilder rawEntity = new StringBuilder ();
+#endif
+                       StringBuilder entity = new StringBuilder ();
+                       StringBuilder output = new StringBuilder ();
+                       int len = s.Length;
+                       // 0 -> nothing,
+                       // 1 -> right after '&'
+                       // 2 -> between '&' and ';' but no '#'
+                       // 3 -> '#' found after '&' and getting numbers
+                       int state = 0;
+                       int number = 0;
+                       bool is_hex_value = false;
+                       bool have_trailing_digits = false;
+       
+                       for (int i = 0; i < len; i++) {
+                               char c = s [i];
+                               if (state == 0) {
+                                       if (c == '&') {
+                                               entity.Append (c);
+#if NET_4_0
+                                               rawEntity.Append (c);
+#endif
+                                               state = 1;
+                                       } else {
+                                               output.Append (c);
+                                       }
+                                       continue;
+                               }
+
+                               if (c == '&') {
+                                       state = 1;
+                                       if (have_trailing_digits) {
+                                               entity.Append (number.ToString (Helpers.InvariantCulture));
+                                               have_trailing_digits = false;
+                                       }
+
+                                       output.Append (entity.ToString ());
+                                       entity.Length = 0;
+                                       entity.Append ('&');
+                                       continue;
+                               }
+
+                               if (state == 1) {
+                                       if (c == ';') {
+                                               state = 0;
+                                               output.Append (entity.ToString ());
+                                               output.Append (c);
+                                               entity.Length = 0;
+                                       } else {
+                                               number = 0;
+                                               is_hex_value = false;
+                                               if (c != '#') {
+                                                       state = 2;
+                                               } else {
+                                                       state = 3;
+                                               }
+                                               entity.Append (c);
+#if NET_4_0
+                                               rawEntity.Append (c);
+#endif
+                                       }
+                               } else if (state == 2) {
+                                       entity.Append (c);
+                                       if (c == ';') {
+                                               string key = entity.ToString ();
+                                               if (key.Length > 1 && Entities.ContainsKey (key.Substring (1, key.Length - 2)))
+                                                       key = Entities [key.Substring (1, key.Length - 2)].ToString ();
+
+                                               output.Append (key);
+                                               state = 0;
+                                               entity.Length = 0;
+#if NET_4_0
+                                               rawEntity.Length = 0;
+#endif
+                                       }
+                               } else if (state == 3) {
+                                       if (c == ';') {
+#if NET_4_0
+                                               if (number == 0)
+                                                       output.Append (rawEntity.ToString () + ";");
+                                               else
+#endif
+                                               if (number > 65535) {
+                                                       output.Append ("&#");
+                                                       output.Append (number.ToString (Helpers.InvariantCulture));
+                                                       output.Append (";");
+                                               } else {
+                                                       output.Append ((char) number);
+                                               }
+                                               state = 0;
+                                               entity.Length = 0;
+#if NET_4_0
+                                               rawEntity.Length = 0;
+#endif
+                                               have_trailing_digits = false;
+                                       } else if (is_hex_value &&  Uri.IsHexDigit(c)) {
+                                               number = number * 16 + Uri.FromHex(c);
+                                               have_trailing_digits = true;
+#if NET_4_0
+                                               rawEntity.Append (c);
+#endif
+                                       } else if (Char.IsDigit (c)) {
+                                               number = number * 10 + ((int) c - '0');
+                                               have_trailing_digits = true;
+#if NET_4_0
+                                               rawEntity.Append (c);
+#endif
+                                       } else if (number == 0 && (c == 'x' || c == 'X')) {
+                                               is_hex_value = true;
+#if NET_4_0
+                                               rawEntity.Append (c);
+#endif
+                                       } else {
+                                               state = 2;
+                                               if (have_trailing_digits) {
+                                                       entity.Append (number.ToString (Helpers.InvariantCulture));
+                                                       have_trailing_digits = false;
+                                               }
+                                               entity.Append (c);
+                                       }
+                               }
+                       }
+
+                       if (entity.Length > 0) {
+                               output.Append (entity.ToString ());
+                       } else if (have_trailing_digits) {
+                               output.Append (number.ToString (Helpers.InvariantCulture));
+                       }
+                       return output.ToString ();
+               }
+
+               internal static bool NotEncoded (char c)
+               {
+                       return (c == '!' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_'
+#if !NET_4_0
+                               || c == '\''
+#endif
+                       );
+               }
+               
+               internal static void UrlEncodeChar (char c, Stream result, bool isUnicode) {
+                       if (c > 255) {
+                               //FIXME: what happens when there is an internal error?
+                               //if (!isUnicode)
+                               //      throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
+                               int idx;
+                               int i = (int) c;
+
+                               result.WriteByte ((byte)'%');
+                               result.WriteByte ((byte)'u');
+                               idx = i >> 12;
+                               result.WriteByte ((byte)hexChars [idx]);
+                               idx = (i >> 8) & 0x0F;
+                               result.WriteByte ((byte)hexChars [idx]);
+                               idx = (i >> 4) & 0x0F;
+                               result.WriteByte ((byte)hexChars [idx]);
+                               idx = i & 0x0F;
+                               result.WriteByte ((byte)hexChars [idx]);
+                               return;
+                       }
+                       
+                       if (c > ' ' && NotEncoded (c)) {
+                               result.WriteByte ((byte)c);
+                               return;
+                       }
+                       if (c==' ') {
+                               result.WriteByte ((byte)'+');
+                               return;
+                       }
+                       if (    (c < '0') ||
+                               (c < 'A' && c > '9') ||
+                               (c > 'Z' && c < 'a') ||
+                               (c > 'z')) {
+                               if (isUnicode && c > 127) {
+                                       result.WriteByte ((byte)'%');
+                                       result.WriteByte ((byte)'u');
+                                       result.WriteByte ((byte)'0');
+                                       result.WriteByte ((byte)'0');
+                               }
+                               else
+                                       result.WriteByte ((byte)'%');
+                               
+                               int idx = ((int) c) >> 4;
+                               result.WriteByte ((byte)hexChars [idx]);
+                               idx = ((int) c) & 0x0F;
+                               result.WriteByte ((byte)hexChars [idx]);
+                       }
+                       else
+                               result.WriteByte ((byte)c);
+               }
+
+               internal static void UrlPathEncodeChar (char c, Stream result)
+               {
+                       if (c < 33 || c > 126) {
+                               byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ());
+                               for (int i = 0; i < bIn.Length; i++) {
+                                       result.WriteByte ((byte) '%');
+                                       int idx = ((int) bIn [i]) >> 4;
+                                       result.WriteByte ((byte) hexChars [idx]);
+                                       idx = ((int) bIn [i]) & 0x0F;
+                                       result.WriteByte ((byte) hexChars [idx]);
+                               }
+                       }
+                       else if (c == ' ') {
+                               result.WriteByte ((byte) '%');
+                               result.WriteByte ((byte) '2');
+                               result.WriteByte ((byte) '0');
+                       }
+                       else
+                               result.WriteByte ((byte) c);
+               }
+               
+               static void InitEntities ()
+               {
+                       // Build the hash table of HTML entity references.  This list comes
+                       // from the HTML 4.01 W3C recommendation.
+                       entities = new SortedDictionary <string, char> (StringComparer.Ordinal);
+                       
+                       entities.Add ("nbsp", '\u00A0');
+                       entities.Add ("iexcl", '\u00A1');
+                       entities.Add ("cent", '\u00A2');
+                       entities.Add ("pound", '\u00A3');
+                       entities.Add ("curren", '\u00A4');
+                       entities.Add ("yen", '\u00A5');
+                       entities.Add ("brvbar", '\u00A6');
+                       entities.Add ("sect", '\u00A7');
+                       entities.Add ("uml", '\u00A8');
+                       entities.Add ("copy", '\u00A9');
+                       entities.Add ("ordf", '\u00AA');
+                       entities.Add ("laquo", '\u00AB');
+                       entities.Add ("not", '\u00AC');
+                       entities.Add ("shy", '\u00AD');
+                       entities.Add ("reg", '\u00AE');
+                       entities.Add ("macr", '\u00AF');
+                       entities.Add ("deg", '\u00B0');
+                       entities.Add ("plusmn", '\u00B1');
+                       entities.Add ("sup2", '\u00B2');
+                       entities.Add ("sup3", '\u00B3');
+                       entities.Add ("acute", '\u00B4');
+                       entities.Add ("micro", '\u00B5');
+                       entities.Add ("para", '\u00B6');
+                       entities.Add ("middot", '\u00B7');
+                       entities.Add ("cedil", '\u00B8');
+                       entities.Add ("sup1", '\u00B9');
+                       entities.Add ("ordm", '\u00BA');
+                       entities.Add ("raquo", '\u00BB');
+                       entities.Add ("frac14", '\u00BC');
+                       entities.Add ("frac12", '\u00BD');
+                       entities.Add ("frac34", '\u00BE');
+                       entities.Add ("iquest", '\u00BF');
+                       entities.Add ("Agrave", '\u00C0');
+                       entities.Add ("Aacute", '\u00C1');
+                       entities.Add ("Acirc", '\u00C2');
+                       entities.Add ("Atilde", '\u00C3');
+                       entities.Add ("Auml", '\u00C4');
+                       entities.Add ("Aring", '\u00C5');
+                       entities.Add ("AElig", '\u00C6');
+                       entities.Add ("Ccedil", '\u00C7');
+                       entities.Add ("Egrave", '\u00C8');
+                       entities.Add ("Eacute", '\u00C9');
+                       entities.Add ("Ecirc", '\u00CA');
+                       entities.Add ("Euml", '\u00CB');
+                       entities.Add ("Igrave", '\u00CC');
+                       entities.Add ("Iacute", '\u00CD');
+                       entities.Add ("Icirc", '\u00CE');
+                       entities.Add ("Iuml", '\u00CF');
+                       entities.Add ("ETH", '\u00D0');
+                       entities.Add ("Ntilde", '\u00D1');
+                       entities.Add ("Ograve", '\u00D2');
+                       entities.Add ("Oacute", '\u00D3');
+                       entities.Add ("Ocirc", '\u00D4');
+                       entities.Add ("Otilde", '\u00D5');
+                       entities.Add ("Ouml", '\u00D6');
+                       entities.Add ("times", '\u00D7');
+                       entities.Add ("Oslash", '\u00D8');
+                       entities.Add ("Ugrave", '\u00D9');
+                       entities.Add ("Uacute", '\u00DA');
+                       entities.Add ("Ucirc", '\u00DB');
+                       entities.Add ("Uuml", '\u00DC');
+                       entities.Add ("Yacute", '\u00DD');
+                       entities.Add ("THORN", '\u00DE');
+                       entities.Add ("szlig", '\u00DF');
+                       entities.Add ("agrave", '\u00E0');
+                       entities.Add ("aacute", '\u00E1');
+                       entities.Add ("acirc", '\u00E2');
+                       entities.Add ("atilde", '\u00E3');
+                       entities.Add ("auml", '\u00E4');
+                       entities.Add ("aring", '\u00E5');
+                       entities.Add ("aelig", '\u00E6');
+                       entities.Add ("ccedil", '\u00E7');
+                       entities.Add ("egrave", '\u00E8');
+                       entities.Add ("eacute", '\u00E9');
+                       entities.Add ("ecirc", '\u00EA');
+                       entities.Add ("euml", '\u00EB');
+                       entities.Add ("igrave", '\u00EC');
+                       entities.Add ("iacute", '\u00ED');
+                       entities.Add ("icirc", '\u00EE');
+                       entities.Add ("iuml", '\u00EF');
+                       entities.Add ("eth", '\u00F0');
+                       entities.Add ("ntilde", '\u00F1');
+                       entities.Add ("ograve", '\u00F2');
+                       entities.Add ("oacute", '\u00F3');
+                       entities.Add ("ocirc", '\u00F4');
+                       entities.Add ("otilde", '\u00F5');
+                       entities.Add ("ouml", '\u00F6');
+                       entities.Add ("divide", '\u00F7');
+                       entities.Add ("oslash", '\u00F8');
+                       entities.Add ("ugrave", '\u00F9');
+                       entities.Add ("uacute", '\u00FA');
+                       entities.Add ("ucirc", '\u00FB');
+                       entities.Add ("uuml", '\u00FC');
+                       entities.Add ("yacute", '\u00FD');
+                       entities.Add ("thorn", '\u00FE');
+                       entities.Add ("yuml", '\u00FF');
+                       entities.Add ("fnof", '\u0192');
+                       entities.Add ("Alpha", '\u0391');
+                       entities.Add ("Beta", '\u0392');
+                       entities.Add ("Gamma", '\u0393');
+                       entities.Add ("Delta", '\u0394');
+                       entities.Add ("Epsilon", '\u0395');
+                       entities.Add ("Zeta", '\u0396');
+                       entities.Add ("Eta", '\u0397');
+                       entities.Add ("Theta", '\u0398');
+                       entities.Add ("Iota", '\u0399');
+                       entities.Add ("Kappa", '\u039A');
+                       entities.Add ("Lambda", '\u039B');
+                       entities.Add ("Mu", '\u039C');
+                       entities.Add ("Nu", '\u039D');
+                       entities.Add ("Xi", '\u039E');
+                       entities.Add ("Omicron", '\u039F');
+                       entities.Add ("Pi", '\u03A0');
+                       entities.Add ("Rho", '\u03A1');
+                       entities.Add ("Sigma", '\u03A3');
+                       entities.Add ("Tau", '\u03A4');
+                       entities.Add ("Upsilon", '\u03A5');
+                       entities.Add ("Phi", '\u03A6');
+                       entities.Add ("Chi", '\u03A7');
+                       entities.Add ("Psi", '\u03A8');
+                       entities.Add ("Omega", '\u03A9');
+                       entities.Add ("alpha", '\u03B1');
+                       entities.Add ("beta", '\u03B2');
+                       entities.Add ("gamma", '\u03B3');
+                       entities.Add ("delta", '\u03B4');
+                       entities.Add ("epsilon", '\u03B5');
+                       entities.Add ("zeta", '\u03B6');
+                       entities.Add ("eta", '\u03B7');
+                       entities.Add ("theta", '\u03B8');
+                       entities.Add ("iota", '\u03B9');
+                       entities.Add ("kappa", '\u03BA');
+                       entities.Add ("lambda", '\u03BB');
+                       entities.Add ("mu", '\u03BC');
+                       entities.Add ("nu", '\u03BD');
+                       entities.Add ("xi", '\u03BE');
+                       entities.Add ("omicron", '\u03BF');
+                       entities.Add ("pi", '\u03C0');
+                       entities.Add ("rho", '\u03C1');
+                       entities.Add ("sigmaf", '\u03C2');
+                       entities.Add ("sigma", '\u03C3');
+                       entities.Add ("tau", '\u03C4');
+                       entities.Add ("upsilon", '\u03C5');
+                       entities.Add ("phi", '\u03C6');
+                       entities.Add ("chi", '\u03C7');
+                       entities.Add ("psi", '\u03C8');
+                       entities.Add ("omega", '\u03C9');
+                       entities.Add ("thetasym", '\u03D1');
+                       entities.Add ("upsih", '\u03D2');
+                       entities.Add ("piv", '\u03D6');
+                       entities.Add ("bull", '\u2022');
+                       entities.Add ("hellip", '\u2026');
+                       entities.Add ("prime", '\u2032');
+                       entities.Add ("Prime", '\u2033');
+                       entities.Add ("oline", '\u203E');
+                       entities.Add ("frasl", '\u2044');
+                       entities.Add ("weierp", '\u2118');
+                       entities.Add ("image", '\u2111');
+                       entities.Add ("real", '\u211C');
+                       entities.Add ("trade", '\u2122');
+                       entities.Add ("alefsym", '\u2135');
+                       entities.Add ("larr", '\u2190');
+                       entities.Add ("uarr", '\u2191');
+                       entities.Add ("rarr", '\u2192');
+                       entities.Add ("darr", '\u2193');
+                       entities.Add ("harr", '\u2194');
+                       entities.Add ("crarr", '\u21B5');
+                       entities.Add ("lArr", '\u21D0');
+                       entities.Add ("uArr", '\u21D1');
+                       entities.Add ("rArr", '\u21D2');
+                       entities.Add ("dArr", '\u21D3');
+                       entities.Add ("hArr", '\u21D4');
+                       entities.Add ("forall", '\u2200');
+                       entities.Add ("part", '\u2202');
+                       entities.Add ("exist", '\u2203');
+                       entities.Add ("empty", '\u2205');
+                       entities.Add ("nabla", '\u2207');
+                       entities.Add ("isin", '\u2208');
+                       entities.Add ("notin", '\u2209');
+                       entities.Add ("ni", '\u220B');
+                       entities.Add ("prod", '\u220F');
+                       entities.Add ("sum", '\u2211');
+                       entities.Add ("minus", '\u2212');
+                       entities.Add ("lowast", '\u2217');
+                       entities.Add ("radic", '\u221A');
+                       entities.Add ("prop", '\u221D');
+                       entities.Add ("infin", '\u221E');
+                       entities.Add ("ang", '\u2220');
+                       entities.Add ("and", '\u2227');
+                       entities.Add ("or", '\u2228');
+                       entities.Add ("cap", '\u2229');
+                       entities.Add ("cup", '\u222A');
+                       entities.Add ("int", '\u222B');
+                       entities.Add ("there4", '\u2234');
+                       entities.Add ("sim", '\u223C');
+                       entities.Add ("cong", '\u2245');
+                       entities.Add ("asymp", '\u2248');
+                       entities.Add ("ne", '\u2260');
+                       entities.Add ("equiv", '\u2261');
+                       entities.Add ("le", '\u2264');
+                       entities.Add ("ge", '\u2265');
+                       entities.Add ("sub", '\u2282');
+                       entities.Add ("sup", '\u2283');
+                       entities.Add ("nsub", '\u2284');
+                       entities.Add ("sube", '\u2286');
+                       entities.Add ("supe", '\u2287');
+                       entities.Add ("oplus", '\u2295');
+                       entities.Add ("otimes", '\u2297');
+                       entities.Add ("perp", '\u22A5');
+                       entities.Add ("sdot", '\u22C5');
+                       entities.Add ("lceil", '\u2308');
+                       entities.Add ("rceil", '\u2309');
+                       entities.Add ("lfloor", '\u230A');
+                       entities.Add ("rfloor", '\u230B');
+                       entities.Add ("lang", '\u2329');
+                       entities.Add ("rang", '\u232A');
+                       entities.Add ("loz", '\u25CA');
+                       entities.Add ("spades", '\u2660');
+                       entities.Add ("clubs", '\u2663');
+                       entities.Add ("hearts", '\u2665');
+                       entities.Add ("diams", '\u2666');
+                       entities.Add ("quot", '\u0022');
+                       entities.Add ("amp", '\u0026');
+                       entities.Add ("lt", '\u003C');
+                       entities.Add ("gt", '\u003E');
+                       entities.Add ("OElig", '\u0152');
+                       entities.Add ("oelig", '\u0153');
+                       entities.Add ("Scaron", '\u0160');
+                       entities.Add ("scaron", '\u0161');
+                       entities.Add ("Yuml", '\u0178');
+                       entities.Add ("circ", '\u02C6');
+                       entities.Add ("tilde", '\u02DC');
+                       entities.Add ("ensp", '\u2002');
+                       entities.Add ("emsp", '\u2003');
+                       entities.Add ("thinsp", '\u2009');
+                       entities.Add ("zwnj", '\u200C');
+                       entities.Add ("zwj", '\u200D');
+                       entities.Add ("lrm", '\u200E');
+                       entities.Add ("rlm", '\u200F');
+                       entities.Add ("ndash", '\u2013');
+                       entities.Add ("mdash", '\u2014');
+                       entities.Add ("lsquo", '\u2018');
+                       entities.Add ("rsquo", '\u2019');
+                       entities.Add ("sbquo", '\u201A');
+                       entities.Add ("ldquo", '\u201C');
+                       entities.Add ("rdquo", '\u201D');
+                       entities.Add ("bdquo", '\u201E');
+                       entities.Add ("dagger", '\u2020');
+                       entities.Add ("Dagger", '\u2021');
+                       entities.Add ("permil", '\u2030');
+                       entities.Add ("lsaquo", '\u2039');
+                       entities.Add ("rsaquo", '\u203A');
+                       entities.Add ("euro", '\u20AC');
+               }
+       }
+}
index 028d45f68244d8fe877555545f89251f8c6d8f6c..4c9c2364de36f127faa949595af39ead0af6a526 100644 (file)
@@ -303,6 +303,7 @@ System.Web/HttpCookieMode.cs
 System.Web/HttpException.cs
 System.Web/HttpFileCollection.cs
 System.Web/HttpForbiddenHandler.cs
+System.Web/HttpHeaderCollection.cs
 System.Web/HttpMethodNotAllowedHandler.cs
 System.Web/HttpModuleCollection.cs
 System.Web/HttpParamsCollection.cs
@@ -1158,6 +1159,7 @@ System.Web.Util/DataSourceHelper.cs
 System.Web.Util/DataSourceResolver.cs
 System.Web.Util/FileUtils.cs
 System.Web.Util/Helpers.cs
+System.Web.Util/HttpEncoder.cs
 System.Web.Util/ICalls.cs
 System.Web.Util/IWebObjectFactory.cs
 System.Web.Util/IWebPropertyAccessor.cs
index d3d949446b5ff2b2309c8332e478750d1b884955..f0022cd955c897da64c7810682aac66193e8e66d 100644 (file)
@@ -1,3 +1,20 @@
+2010-06-01  Marek Habersack  <mhabersack@novell.com>
+
+       * HttpUtility.cs: moved chunks of code to the new
+       System.Web.Util.HttpEncoder class.
+
+       * HttpResponseHeader.cs: encode header names and values using
+       HttpEncoder.
+
+       * HttpRequest.cs: added internal method Validate, to validate the
+       request in 4.0 profile.
+
+       * HttpHeaderCollection.cs: added. A helper class to encode header
+       names/values on add.
+
+       * HttpApplication.cs: Pipeline () validates request by calling
+       HttpRequest.Validate in the 4.0 profile.
+
 2010-05-17  Marek Habersack  <mhabersack@novell.com>
 
        * HttpApplicationFactory.cs: pre-application start methods must be
index d9972ceddec874d60ed40d8dafba25186e78fad8..49295dec49bd7fad2eac4b0cd8477b0fddbfe3a1 100644 (file)
@@ -1174,21 +1174,10 @@ namespace System.Web
                        Delegate eventHandler;
                        if (stop_processing)
                                yield return true;
-
 #if NET_4_0
-                       if (HttpRequest.ValidateRequestNewMode) {
-                               char[] invalidChars = HttpRequest.RequestPathInvalidCharacters;
-                               HttpRequest req = context.Request;
-                               if (invalidChars != null && req != null) {
-                                       string path = req.PathNoValidation;
-                                       int idx = path != null ? path.IndexOfAny (invalidChars) : -1;
-                                       if (idx != -1)
-                                               throw HttpException.NewWithCode (
-                                                       String.Format ("A potentially dangerous Request.Path value was detected from the client ({0}).", path [idx]),
-                                                       WebEventCodes.RuntimeErrorValidationFailure
-                                               );
-                               }
-                       }
+                       HttpRequest req = context.Request;
+                       if (req != null)
+                               req.Validate ();
 #endif
                        context.MapRequestHandlerDone = false;
                        StartTimer ("BeginRequest");
diff --git a/mcs/class/System.Web/System.Web/HttpHeaderCollection.cs b/mcs/class/System.Web/System.Web/HttpHeaderCollection.cs
new file mode 100644 (file)
index 0000000..c07c106
--- /dev/null
@@ -0,0 +1,81 @@
+//
+// Authors:
+//      Marek Habersack <mhabersack@novell.com>
+//
+// Copyright (C) 2010 Novell, Inc (http://www.novell.com)
+//
+// 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.
+//
+using System;
+using System.Collections.Specialized;
+using System.Web.Configuration;
+using System.Web.Util;
+
+namespace System.Web
+{
+       sealed class HttpHeaderCollection : NameValueCollection
+       {
+               bool? headerCheckingEnabled;
+
+               bool HeaderCheckingEnabled {
+                       get {
+                               if (headerCheckingEnabled == null) {
+                                       var cfg = WebConfigurationManager.GetSection ("system.web/httpRuntime") as HttpRuntimeSection;
+                                       headerCheckingEnabled = cfg.EnableHeaderChecking;
+                               }
+
+                               return (bool)headerCheckingEnabled;
+                       }
+               }
+                               
+               public override void Add (string name, string value)
+               {
+                       EncodeAndSetHeader (name, value, false);
+               }
+
+               public override void Set (string name, string value)
+               {
+                       EncodeAndSetHeader (name, value, true);
+               }
+
+               void EncodeAndSetHeader (string name, string value, bool replaceExisting)
+               {
+                       if (String.IsNullOrEmpty (name) || String.IsNullOrEmpty (value))
+                               return;
+
+                       string encName, encValue;
+                       if (HeaderCheckingEnabled) {
+#if NET_4_0
+                               HttpEncoder.Current.HeaderNameValueEncode (name, value, out encName, out encValue);
+#else
+                               HttpEncoder.HeaderNameValueEncode (name, value, out encName, out encValue);
+#endif
+                       } else {
+                               encName = name;
+                               encValue = value;
+                       }
+
+                       if (replaceExisting)
+                               base.Set (encName, encValue);
+                       else
+                               base.Add (encName, encValue);
+               }
+       }
+}
index 6f4ebe05cbae77ff7b4814540308d0c4bb99ca46..f4e2e5112dc252065789d95e705cc1a7049ce790 100644 (file)
@@ -1410,7 +1410,32 @@ namespace System.Web
                        validate_query_string = true;
                        validate_form = true;
                }
-
+#if NET_4_0
+               internal void Validate ()
+               {
+                       var cfg = WebConfigurationManager.GetSection ("system.web/httpRuntime") as HttpRuntimeSection;
+                       string query = UrlComponents.Query;
+                       
+                       if (query != null && query.Length > cfg.MaxQueryStringLength)
+                               throw new HttpException (400, "The length of the query string for this request exceeds the configured maxQueryStringLength value.");
+                       
+                       string path = PathNoValidation;
+                       if (path != null) {
+                               if (path.Length > cfg.MaxUrlLength)
+                                       throw new HttpException (400, "The length of the URL for this request exceeds the configured maxUrlLength value.");
+                               
+                               char[] invalidChars = RequestPathInvalidCharacters;
+                               if (invalidChars != null) {
+                                       int idx = path.IndexOfAny (invalidChars);
+                                       if (idx != -1)
+                                               throw HttpException.NewWithCode (
+                                                       String.Format ("A potentially dangerous Request.Path value was detected from the client ({0}).", path [idx]),
+                                                       WebEventCodes.RuntimeErrorValidationFailure
+                                               );
+                               }
+                       }
+               }
+#endif
 #region internal routines
                internal string ClientTarget {
                        get {
index f5a3eb9470caa8f71c42d0f3e140da74e88a8e23..9aa99d9244bba7f1fefdf3e5dd6a763be74ae5a0 100644 (file)
@@ -7,7 +7,7 @@
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //      Marek Habersack <mhabersack@novell.com>
 //
-// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -88,7 +88,7 @@ namespace System.Web
                // the headers that we compute here.
                //
 
-               NameValueCollection headers;
+               HttpHeaderCollection headers;
                bool headers_sent;
                NameValueCollection cached_headers;
 
@@ -324,7 +324,7 @@ namespace System.Web
                public NameValueCollection Headers {
                        get {
                                if (headers == null)
-                                       headers = new NameValueCollection ();
+                                       headers = new HttpHeaderCollection ();
 
                                return headers;
                        }
@@ -502,8 +502,7 @@ namespace System.Web
                public void AppendHeader (string name, string value)
                {
                        if (headers_sent)
-                               throw new HttpException ("headers have been already sent");
-                       
+                               throw new HttpException ("Headers have been already sent");
 #if !TARGET_J2EE
                        if (String.Compare (name, "content-length", true, Helpers.InvariantCulture) == 0){
                                content_length = (long) UInt64.Parse (value);
index 47cc9e760a6eda96980755657201276add3a7385..432129dcae2392ad633ccb2d6e91f3a68d3311ab 100644 (file)
@@ -6,7 +6,7 @@
 //
 
 //
-// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -31,6 +31,7 @@
 using System.Collections;
 using System.Text;
 using System.Web.Configuration;
+using System.Web.Util;
 
 namespace System.Web
 {
@@ -40,7 +41,15 @@ namespace System.Web
                
                public string Value {
                        get { return headerValue; }
-                       set { headerValue = EncodeHeader (value); }
+                       set {
+                               string hname, hvalue;
+#if NET_4_0
+                               HttpEncoder.Current.HeaderNameValueEncode (null, value, out hname, out hvalue);
+#else
+                               HttpEncoder.HeaderNameValueEncode (null, value, out hname, out hvalue);
+#endif
+                               headerValue = hvalue;
+                       }
                }
          
                static bool headerCheckingEnabled;
@@ -56,41 +65,12 @@ namespace System.Web
                {
                        Value = val;
                }
-
-               string EncodeHeader (string value)
-               {
-                       if (value == null || value.Length == 0)
-                               return value;
-                       
-                       if (headerCheckingEnabled) {
-                               StringBuilder ret = new StringBuilder ();
-                               int len = value.Length;
-
-                               for (int i = 0; i < len; i++) {
-                                       switch (value [i]) {
-                                               case '\r':
-                                                       ret.Append ("%0d");
-                                                       break;
-
-                                               case '\n':
-                                                       ret.Append ("%0a");
-                                                       break;
-
-                                               default:
-                                                       ret.Append (value [i]);
-                                                       break;
-                                       }
-                               }
-
-                               return ret.ToString ();
-                       } else
-                               return value;
-               }
                
                internal abstract void SendContent (HttpWorkerRequest wr);
        }
 
-       internal sealed class KnownResponseHeader : BaseResponseHeader {
+       internal sealed class KnownResponseHeader : BaseResponseHeader
+       {
                public int ID;
 
                internal KnownResponseHeader (int ID, string val) : base (val)
@@ -104,8 +84,23 @@ namespace System.Web
                }
        }
 
-       internal  class UnknownResponseHeader : BaseResponseHeader {
-               public string Name;
+       internal sealed class UnknownResponseHeader : BaseResponseHeader
+       {
+               string headerName;
+               
+               public string Name {
+                       get { return headerName; }
+                       set {
+                               string hname, hvalue;
+#if NET_4_0
+                               HttpEncoder.Current.HeaderNameValueEncode (value, null, out hname, out hvalue);
+#else
+                               HttpEncoder.HeaderNameValueEncode (value, null, out hname, out hvalue);
+#endif
+                               headerName = hname;
+                       }
+               }
+               
 
                public UnknownResponseHeader (string name, string val) : base (val)
                {
index 8334f6b1d0a4b0dcd90cca2fd950d21ceeb13fa7..7750e95e14d896b240a6e14650a670d1cd263b60 100644 (file)
@@ -7,7 +7,7 @@
 //   Tim Coleman (tim@timcoleman.com)
 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //
-// Copyright (C) 2005-2009 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -63,285 +63,9 @@ namespace System.Web {
                                return sb.ToString ();
                        }
                }
-               #region Fields
-       
-               static Hashtable entities;
-               static object lock_ = new object ();
-       
-               #endregion // Fields
-       
-               static Hashtable Entities {
-                       get {
-                               lock (lock_) {
-                                       if (entities == null)
-                                               InitEntities ();
-
-                                       return entities;
-                               }
-                       }
-               }
                
                #region Constructors
 
-               static void InitEntities ()
-               {
-                       // Build the hash table of HTML entity references.  This list comes
-                       // from the HTML 4.01 W3C recommendation.
-                       entities = new Hashtable ();
-                       entities.Add ("nbsp", '\u00A0');
-                       entities.Add ("iexcl", '\u00A1');
-                       entities.Add ("cent", '\u00A2');
-                       entities.Add ("pound", '\u00A3');
-                       entities.Add ("curren", '\u00A4');
-                       entities.Add ("yen", '\u00A5');
-                       entities.Add ("brvbar", '\u00A6');
-                       entities.Add ("sect", '\u00A7');
-                       entities.Add ("uml", '\u00A8');
-                       entities.Add ("copy", '\u00A9');
-                       entities.Add ("ordf", '\u00AA');
-                       entities.Add ("laquo", '\u00AB');
-                       entities.Add ("not", '\u00AC');
-                       entities.Add ("shy", '\u00AD');
-                       entities.Add ("reg", '\u00AE');
-                       entities.Add ("macr", '\u00AF');
-                       entities.Add ("deg", '\u00B0');
-                       entities.Add ("plusmn", '\u00B1');
-                       entities.Add ("sup2", '\u00B2');
-                       entities.Add ("sup3", '\u00B3');
-                       entities.Add ("acute", '\u00B4');
-                       entities.Add ("micro", '\u00B5');
-                       entities.Add ("para", '\u00B6');
-                       entities.Add ("middot", '\u00B7');
-                       entities.Add ("cedil", '\u00B8');
-                       entities.Add ("sup1", '\u00B9');
-                       entities.Add ("ordm", '\u00BA');
-                       entities.Add ("raquo", '\u00BB');
-                       entities.Add ("frac14", '\u00BC');
-                       entities.Add ("frac12", '\u00BD');
-                       entities.Add ("frac34", '\u00BE');
-                       entities.Add ("iquest", '\u00BF');
-                       entities.Add ("Agrave", '\u00C0');
-                       entities.Add ("Aacute", '\u00C1');
-                       entities.Add ("Acirc", '\u00C2');
-                       entities.Add ("Atilde", '\u00C3');
-                       entities.Add ("Auml", '\u00C4');
-                       entities.Add ("Aring", '\u00C5');
-                       entities.Add ("AElig", '\u00C6');
-                       entities.Add ("Ccedil", '\u00C7');
-                       entities.Add ("Egrave", '\u00C8');
-                       entities.Add ("Eacute", '\u00C9');
-                       entities.Add ("Ecirc", '\u00CA');
-                       entities.Add ("Euml", '\u00CB');
-                       entities.Add ("Igrave", '\u00CC');
-                       entities.Add ("Iacute", '\u00CD');
-                       entities.Add ("Icirc", '\u00CE');
-                       entities.Add ("Iuml", '\u00CF');
-                       entities.Add ("ETH", '\u00D0');
-                       entities.Add ("Ntilde", '\u00D1');
-                       entities.Add ("Ograve", '\u00D2');
-                       entities.Add ("Oacute", '\u00D3');
-                       entities.Add ("Ocirc", '\u00D4');
-                       entities.Add ("Otilde", '\u00D5');
-                       entities.Add ("Ouml", '\u00D6');
-                       entities.Add ("times", '\u00D7');
-                       entities.Add ("Oslash", '\u00D8');
-                       entities.Add ("Ugrave", '\u00D9');
-                       entities.Add ("Uacute", '\u00DA');
-                       entities.Add ("Ucirc", '\u00DB');
-                       entities.Add ("Uuml", '\u00DC');
-                       entities.Add ("Yacute", '\u00DD');
-                       entities.Add ("THORN", '\u00DE');
-                       entities.Add ("szlig", '\u00DF');
-                       entities.Add ("agrave", '\u00E0');
-                       entities.Add ("aacute", '\u00E1');
-                       entities.Add ("acirc", '\u00E2');
-                       entities.Add ("atilde", '\u00E3');
-                       entities.Add ("auml", '\u00E4');
-                       entities.Add ("aring", '\u00E5');
-                       entities.Add ("aelig", '\u00E6');
-                       entities.Add ("ccedil", '\u00E7');
-                       entities.Add ("egrave", '\u00E8');
-                       entities.Add ("eacute", '\u00E9');
-                       entities.Add ("ecirc", '\u00EA');
-                       entities.Add ("euml", '\u00EB');
-                       entities.Add ("igrave", '\u00EC');
-                       entities.Add ("iacute", '\u00ED');
-                       entities.Add ("icirc", '\u00EE');
-                       entities.Add ("iuml", '\u00EF');
-                       entities.Add ("eth", '\u00F0');
-                       entities.Add ("ntilde", '\u00F1');
-                       entities.Add ("ograve", '\u00F2');
-                       entities.Add ("oacute", '\u00F3');
-                       entities.Add ("ocirc", '\u00F4');
-                       entities.Add ("otilde", '\u00F5');
-                       entities.Add ("ouml", '\u00F6');
-                       entities.Add ("divide", '\u00F7');
-                       entities.Add ("oslash", '\u00F8');
-                       entities.Add ("ugrave", '\u00F9');
-                       entities.Add ("uacute", '\u00FA');
-                       entities.Add ("ucirc", '\u00FB');
-                       entities.Add ("uuml", '\u00FC');
-                       entities.Add ("yacute", '\u00FD');
-                       entities.Add ("thorn", '\u00FE');
-                       entities.Add ("yuml", '\u00FF');
-                       entities.Add ("fnof", '\u0192');
-                       entities.Add ("Alpha", '\u0391');
-                       entities.Add ("Beta", '\u0392');
-                       entities.Add ("Gamma", '\u0393');
-                       entities.Add ("Delta", '\u0394');
-                       entities.Add ("Epsilon", '\u0395');
-                       entities.Add ("Zeta", '\u0396');
-                       entities.Add ("Eta", '\u0397');
-                       entities.Add ("Theta", '\u0398');
-                       entities.Add ("Iota", '\u0399');
-                       entities.Add ("Kappa", '\u039A');
-                       entities.Add ("Lambda", '\u039B');
-                       entities.Add ("Mu", '\u039C');
-                       entities.Add ("Nu", '\u039D');
-                       entities.Add ("Xi", '\u039E');
-                       entities.Add ("Omicron", '\u039F');
-                       entities.Add ("Pi", '\u03A0');
-                       entities.Add ("Rho", '\u03A1');
-                       entities.Add ("Sigma", '\u03A3');
-                       entities.Add ("Tau", '\u03A4');
-                       entities.Add ("Upsilon", '\u03A5');
-                       entities.Add ("Phi", '\u03A6');
-                       entities.Add ("Chi", '\u03A7');
-                       entities.Add ("Psi", '\u03A8');
-                       entities.Add ("Omega", '\u03A9');
-                       entities.Add ("alpha", '\u03B1');
-                       entities.Add ("beta", '\u03B2');
-                       entities.Add ("gamma", '\u03B3');
-                       entities.Add ("delta", '\u03B4');
-                       entities.Add ("epsilon", '\u03B5');
-                       entities.Add ("zeta", '\u03B6');
-                       entities.Add ("eta", '\u03B7');
-                       entities.Add ("theta", '\u03B8');
-                       entities.Add ("iota", '\u03B9');
-                       entities.Add ("kappa", '\u03BA');
-                       entities.Add ("lambda", '\u03BB');
-                       entities.Add ("mu", '\u03BC');
-                       entities.Add ("nu", '\u03BD');
-                       entities.Add ("xi", '\u03BE');
-                       entities.Add ("omicron", '\u03BF');
-                       entities.Add ("pi", '\u03C0');
-                       entities.Add ("rho", '\u03C1');
-                       entities.Add ("sigmaf", '\u03C2');
-                       entities.Add ("sigma", '\u03C3');
-                       entities.Add ("tau", '\u03C4');
-                       entities.Add ("upsilon", '\u03C5');
-                       entities.Add ("phi", '\u03C6');
-                       entities.Add ("chi", '\u03C7');
-                       entities.Add ("psi", '\u03C8');
-                       entities.Add ("omega", '\u03C9');
-                       entities.Add ("thetasym", '\u03D1');
-                       entities.Add ("upsih", '\u03D2');
-                       entities.Add ("piv", '\u03D6');
-                       entities.Add ("bull", '\u2022');
-                       entities.Add ("hellip", '\u2026');
-                       entities.Add ("prime", '\u2032');
-                       entities.Add ("Prime", '\u2033');
-                       entities.Add ("oline", '\u203E');
-                       entities.Add ("frasl", '\u2044');
-                       entities.Add ("weierp", '\u2118');
-                       entities.Add ("image", '\u2111');
-                       entities.Add ("real", '\u211C');
-                       entities.Add ("trade", '\u2122');
-                       entities.Add ("alefsym", '\u2135');
-                       entities.Add ("larr", '\u2190');
-                       entities.Add ("uarr", '\u2191');
-                       entities.Add ("rarr", '\u2192');
-                       entities.Add ("darr", '\u2193');
-                       entities.Add ("harr", '\u2194');
-                       entities.Add ("crarr", '\u21B5');
-                       entities.Add ("lArr", '\u21D0');
-                       entities.Add ("uArr", '\u21D1');
-                       entities.Add ("rArr", '\u21D2');
-                       entities.Add ("dArr", '\u21D3');
-                       entities.Add ("hArr", '\u21D4');
-                       entities.Add ("forall", '\u2200');
-                       entities.Add ("part", '\u2202');
-                       entities.Add ("exist", '\u2203');
-                       entities.Add ("empty", '\u2205');
-                       entities.Add ("nabla", '\u2207');
-                       entities.Add ("isin", '\u2208');
-                       entities.Add ("notin", '\u2209');
-                       entities.Add ("ni", '\u220B');
-                       entities.Add ("prod", '\u220F');
-                       entities.Add ("sum", '\u2211');
-                       entities.Add ("minus", '\u2212');
-                       entities.Add ("lowast", '\u2217');
-                       entities.Add ("radic", '\u221A');
-                       entities.Add ("prop", '\u221D');
-                       entities.Add ("infin", '\u221E');
-                       entities.Add ("ang", '\u2220');
-                       entities.Add ("and", '\u2227');
-                       entities.Add ("or", '\u2228');
-                       entities.Add ("cap", '\u2229');
-                       entities.Add ("cup", '\u222A');
-                       entities.Add ("int", '\u222B');
-                       entities.Add ("there4", '\u2234');
-                       entities.Add ("sim", '\u223C');
-                       entities.Add ("cong", '\u2245');
-                       entities.Add ("asymp", '\u2248');
-                       entities.Add ("ne", '\u2260');
-                       entities.Add ("equiv", '\u2261');
-                       entities.Add ("le", '\u2264');
-                       entities.Add ("ge", '\u2265');
-                       entities.Add ("sub", '\u2282');
-                       entities.Add ("sup", '\u2283');
-                       entities.Add ("nsub", '\u2284');
-                       entities.Add ("sube", '\u2286');
-                       entities.Add ("supe", '\u2287');
-                       entities.Add ("oplus", '\u2295');
-                       entities.Add ("otimes", '\u2297');
-                       entities.Add ("perp", '\u22A5');
-                       entities.Add ("sdot", '\u22C5');
-                       entities.Add ("lceil", '\u2308');
-                       entities.Add ("rceil", '\u2309');
-                       entities.Add ("lfloor", '\u230A');
-                       entities.Add ("rfloor", '\u230B');
-                       entities.Add ("lang", '\u2329');
-                       entities.Add ("rang", '\u232A');
-                       entities.Add ("loz", '\u25CA');
-                       entities.Add ("spades", '\u2660');
-                       entities.Add ("clubs", '\u2663');
-                       entities.Add ("hearts", '\u2665');
-                       entities.Add ("diams", '\u2666');
-                       entities.Add ("quot", '\u0022');
-                       entities.Add ("amp", '\u0026');
-                       entities.Add ("lt", '\u003C');
-                       entities.Add ("gt", '\u003E');
-                       entities.Add ("OElig", '\u0152');
-                       entities.Add ("oelig", '\u0153');
-                       entities.Add ("Scaron", '\u0160');
-                       entities.Add ("scaron", '\u0161');
-                       entities.Add ("Yuml", '\u0178');
-                       entities.Add ("circ", '\u02C6');
-                       entities.Add ("tilde", '\u02DC');
-                       entities.Add ("ensp", '\u2002');
-                       entities.Add ("emsp", '\u2003');
-                       entities.Add ("thinsp", '\u2009');
-                       entities.Add ("zwnj", '\u200C');
-                       entities.Add ("zwj", '\u200D');
-                       entities.Add ("lrm", '\u200E');
-                       entities.Add ("rlm", '\u200F');
-                       entities.Add ("ndash", '\u2013');
-                       entities.Add ("mdash", '\u2014');
-                       entities.Add ("lsquo", '\u2018');
-                       entities.Add ("rsquo", '\u2019');
-                       entities.Add ("sbquo", '\u201A');
-                       entities.Add ("ldquo", '\u201C');
-                       entities.Add ("rdquo", '\u201D');
-                       entities.Add ("bdquo", '\u201E');
-                       entities.Add ("dagger", '\u2020');
-                       entities.Add ("Dagger", '\u2021');
-                       entities.Add ("permil", '\u2030');
-                       entities.Add ("lsaquo", '\u2039');
-                       entities.Add ("rsaquo", '\u203A');
-                       entities.Add ("euro", '\u20AC');
-               }
-
                public HttpUtility () 
                {
                }
@@ -352,54 +76,33 @@ namespace System.Web {
        
                public static void HtmlAttributeEncode (string s, TextWriter output) 
                {
-                       output.Write(HtmlAttributeEncode(s));
+                       if (output == null) {
+#if NET_4_0
+                               throw new ArgumentNullException ("output");
+#else
+                               throw new NullReferenceException (".NET emulation");
+#endif
+                       }
+#if NET_4_0
+                       HttpEncoder.Current.HtmlAttributeEncode (s, output);
+#else
+                       output.Write (HttpEncoder.HtmlAttributeEncode (s));
+#endif
                }
        
                public static string HtmlAttributeEncode (string s) 
                {
-                       if (null == s) 
-                               return null;
-       
-                       bool needEncode = false;
-                       for (int i = 0; i < s.Length; i++) {
-                               char c = s [i];
-                               if (c == '&' || c == '"' || c == '<'
 #if NET_4_0
-                                   || c == '\''
-#endif
-                               ) {
-                                       needEncode = true;
-                                       break;
-                               }
+                       if (s == null)
+                               return null;
+                       
+                       using (var sw = new StringWriter ()) {
+                               HttpEncoder.Current.HtmlAttributeEncode (s, sw);
+                               return sw.ToString ();
                        }
-
-                       if (!needEncode)
-                               return s;
-
-                       StringBuilder output = new StringBuilder ();
-                       int len = s.Length;
-                       for (int i = 0; i < len; i++)
-                               switch (s [i]) {
-                               case '&' : 
-                                       output.Append ("&amp;");
-                                       break;
-                               case '"' :
-                                       output.Append ("&quot;");
-                                       break;
-                               case '<':
-                                       output.Append ("&lt;");
-                                       break;
-#if NET_4_0
-                               case '\'':
-                                       output.Append ("&#39;");
-                                       break;
+#else
+                       return HttpEncoder.HtmlAttributeEncode (s);
 #endif
-                               default:
-                                       output.Append (s [i]);
-                                       break;
-                               }
-       
-                       return output.ToString();
                }
        
                public static string UrlDecode (string str) 
@@ -660,7 +363,7 @@ namespace System.Web {
                        for (int i = 0; i < len; i++) {
                                char c = s [i];
                                if ((c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z')) {
-                                       if (NotEncoded (c))
+                                       if (HttpEncoder.NotEncoded (c))
                                                continue;
 
                                        needEncode = true;
@@ -683,7 +386,7 @@ namespace System.Web {
                                return null;
 
                        if (bytes.Length == 0)
-                               return "";
+                               return String.Empty;
 
                        return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, 0, bytes.Length));
                }
@@ -694,7 +397,7 @@ namespace System.Web {
                                return null;
 
                        if (bytes.Length == 0)
-                               return "";
+                               return String.Empty;
 
                        return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, offset, count));
                }
@@ -709,7 +412,7 @@ namespace System.Web {
                        if (str == null)
                                return null;
 
-                       if (str == "")
+                       if (str.Length == 0)
                                return new byte [0];
 
                        byte [] bytes = e.GetBytes (str);
@@ -727,89 +430,15 @@ namespace System.Web {
                        return UrlEncodeToBytes (bytes, 0, bytes.Length);
                }
 
-               static char [] hexChars = "0123456789abcdef".ToCharArray ();
-
-               static bool NotEncoded (char c)
-               {
-                       return (c == '!' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_'
-#if !NET_4_0
-                               || c == '\''
-#endif
-                       );
-               }
-
-               static void UrlEncodeChar (char c, Stream result, bool isUnicode) {
-                       if (c > 255) {
-                               //FIXME: what happens when there is an internal error?
-                               //if (!isUnicode)
-                               //      throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
-                               int idx;
-                               int i = (int) c;
-
-                               result.WriteByte ((byte)'%');
-                               result.WriteByte ((byte)'u');
-                               idx = i >> 12;
-                               result.WriteByte ((byte)hexChars [idx]);
-                               idx = (i >> 8) & 0x0F;
-                               result.WriteByte ((byte)hexChars [idx]);
-                               idx = (i >> 4) & 0x0F;
-                               result.WriteByte ((byte)hexChars [idx]);
-                               idx = i & 0x0F;
-                               result.WriteByte ((byte)hexChars [idx]);
-                               return;
-                       }
-                       
-                       if (c > ' ' && NotEncoded (c)) {
-                               result.WriteByte ((byte)c);
-                               return;
-                       }
-                       if (c==' ') {
-                               result.WriteByte ((byte)'+');
-                               return;
-                       }
-                       if (    (c < '0') ||
-                               (c < 'A' && c > '9') ||
-                               (c > 'Z' && c < 'a') ||
-                               (c > 'z')) {
-                               if (isUnicode && c > 127) {
-                                       result.WriteByte ((byte)'%');
-                                       result.WriteByte ((byte)'u');
-                                       result.WriteByte ((byte)'0');
-                                       result.WriteByte ((byte)'0');
-                               }
-                               else
-                                       result.WriteByte ((byte)'%');
-                               
-                               int idx = ((int) c) >> 4;
-                               result.WriteByte ((byte)hexChars [idx]);
-                               idx = ((int) c) & 0x0F;
-                               result.WriteByte ((byte)hexChars [idx]);
-                       }
-                       else
-                               result.WriteByte ((byte)c);
-               }
-
                public static byte [] UrlEncodeToBytes (byte [] bytes, int offset, int count)
                {
                        if (bytes == null)
                                return null;
-
-                       int len = bytes.Length;
-                       if (len == 0)
-                               return new byte [0];
-
-                       if (offset < 0 || offset >= len)
-                               throw new ArgumentOutOfRangeException("offset");
-
-                       if (count < 0 || count > len - offset)
-                               throw new ArgumentOutOfRangeException("count");
-
-                       MemoryStream result = new MemoryStream (count);
-                       int end = offset + count;
-                       for (int i = offset; i < end; i++)
-                               UrlEncodeChar ((char)bytes [i], result, false);
-
-                       return result.ToArray();
+#if NET_4_0
+                       return HttpEncoder.Current.UrlEncode (bytes, offset, count);
+#else
+                       return HttpEncoder.UrlEncodeToBytes (bytes, offset, count);
+#endif
                }
 
                public static string UrlEncodeUnicode (string str)
@@ -825,12 +454,12 @@ namespace System.Web {
                        if (str == null)
                                return null;
 
-                       if (str == "")
+                       if (str.Length == 0)
                                return new byte [0];
 
                        MemoryStream result = new MemoryStream (str.Length);
                        foreach (char c in str){
-                               UrlEncodeChar (c, result, true);
+                               HttpEncoder.UrlEncodeChar (c, result, true);
                        }
                        return result.ToArray ();
                }
@@ -842,113 +471,17 @@ namespace System.Web {
                /// <returns>The decoded text.</returns>
                public static string HtmlDecode (string s) 
                {
+#if NET_4_0
                        if (s == null)
-                               throw new ArgumentNullException ("s");
-
-                       if (s.IndexOf ('&') == -1)
-                               return s;
-
-                       StringBuilder entity = new StringBuilder ();
-                       StringBuilder output = new StringBuilder ();
-                       int len = s.Length;
-                       // 0 -> nothing,
-                       // 1 -> right after '&'
-                       // 2 -> between '&' and ';' but no '#'
-                       // 3 -> '#' found after '&' and getting numbers
-                       int state = 0;
-                       int number = 0;
-                       bool is_hex_value = false;
-                       bool have_trailing_digits = false;
-       
-                       for (int i = 0; i < len; i++) {
-                               char c = s [i];
-                               if (state == 0) {
-                                       if (c == '&') {
-                                               entity.Append (c);
-                                               state = 1;
-                                       } else {
-                                               output.Append (c);
-                                       }
-                                       continue;
-                               }
-
-                               if (c == '&') {
-                                       state = 1;
-                                       if (have_trailing_digits) {
-                                               entity.Append (number.ToString (Helpers.InvariantCulture));
-                                               have_trailing_digits = false;
-                                       }
-
-                                       output.Append (entity.ToString ());
-                                       entity.Length = 0;
-                                       entity.Append ('&');
-                                       continue;
-                               }
-
-                               if (state == 1) {
-                                       if (c == ';') {
-                                               state = 0;
-                                               output.Append (entity.ToString ());
-                                               output.Append (c);
-                                               entity.Length = 0;
-                                       } else {
-                                               number = 0;
-                                               is_hex_value = false;
-                                               if (c != '#') {
-                                                       state = 2;
-                                               } else {
-                                                       state = 3;
-                                               }
-                                               entity.Append (c);
-                                       }
-                               } else if (state == 2) {
-                                       entity.Append (c);
-                                       if (c == ';') {
-                                               string key = entity.ToString ();
-                                               if (key.Length > 1 && Entities.ContainsKey (key.Substring (1, key.Length - 2)))
-                                                       key = Entities [key.Substring (1, key.Length - 2)].ToString ();
-
-                                               output.Append (key);
-                                               state = 0;
-                                               entity.Length = 0;
-                                       }
-                               } else if (state == 3) {
-                                       if (c == ';') {
-                                               if (number > 65535) {
-                                                       output.Append ("&#");
-                                                       output.Append (number.ToString (Helpers.InvariantCulture));
-                                                       output.Append (";");
-                                               } else {
-                                                       output.Append ((char) number);
-                                               }
-                                               state = 0;
-                                               entity.Length = 0;
-                                               have_trailing_digits = false;
-                                       } else if (is_hex_value &&  Uri.IsHexDigit(c)) {
-                                               number = number * 16 + Uri.FromHex(c);
-                                               have_trailing_digits = true;
-                                       } else if (Char.IsDigit (c)) {
-                                               number = number * 10 + ((int) c - '0');
-                                               have_trailing_digits = true;
-                                       } else if (number == 0 && (c == 'x' || c == 'X')) {
-                                               is_hex_value = true;
-                                       } else {
-                                               state = 2;
-                                               if (have_trailing_digits) {
-                                                       entity.Append (number.ToString (Helpers.InvariantCulture));
-                                                       have_trailing_digits = false;
-                                               }
-                                               entity.Append (c);
-                                       }
-                               }
-                       }
-
-                       if (entity.Length > 0) {
-                               output.Append (entity.ToString ());
-                       } else if (have_trailing_digits) {
-                               output.Append (number.ToString (Helpers.InvariantCulture));
+                               return null;
+                       
+                       using (var sw = new StringWriter ()) {
+                               HttpEncoder.Current.HtmlDecode (s, sw);
+                               return sw.ToString ();
                        }
-                       return output.ToString ();
+#else
+                       return HttpEncoder.HtmlDecode (s);
+#endif
                }
        
                /// <summary>
@@ -958,78 +491,38 @@ namespace System.Web {
                /// <param name="output">The TextWriter output stream containing the decoded string. </param>
                public static void HtmlDecode(string s, TextWriter output) 
                {
-                       if (s != null)
-                               output.Write (HtmlDecode (s));
-               }
-       
-               /// <summary>
-               /// HTML-encodes a string and returns the encoded string.
-               /// </summary>
-               /// <param name="s">The text string to encode. </param>
-               /// <returns>The HTML-encoded text.</returns>
-               public static string HtmlEncode (string s) 
-               {
-                       if (s == null)
-                               return null;
-
-                       bool needEncode = false;
-                       for (int i = 0; i < s.Length; i++) {
-                               char c = s [i];
-                               if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159
+                       if (output == null) {
 #if NET_4_0
-                                   || c == '\''
+                               throw new ArgumentNullException ("output");
+#else
+                               throw new NullReferenceException (".NET emulation");
 #endif
-                               ) {
-                                       needEncode = true;
-                                       break;
-                               }
                        }
-
-                       if (!needEncode)
-                               return s;
-
-                       StringBuilder output = new StringBuilder ();
-                       
-                       int len = s.Length;
-                       for (int i = 0; i < len; i++) 
-                               switch (s [i]) {
-                               case '&' :
-                                       output.Append ("&amp;");
-                                       break;
-                               case '>' : 
-                                       output.Append ("&gt;");
-                                       break;
-                               case '<' :
-                                       output.Append ("&lt;");
-                                       break;
-                               case '"' :
-                                       output.Append ("&quot;");
-                                       break;
+                               
+                       if (!String.IsNullOrEmpty (s)) {
 #if NET_4_0
-                               case '\'':
-                                       output.Append ("&#39;");
-                                       break;
+                               HttpEncoder.Current.HtmlDecode (s, output);
+#else
+                               output.Write (HttpEncoder.HtmlDecode (s));
 #endif
-                               default:
-                                       // MS starts encoding with &# from 160 and stops at 255.
-                                       // We don't do that. One reason is the 65308/65310 unicode
-                                       // characters that look like '<' and '>'.
-#if TARGET_JVM
-                                       if (s [i] > 159 && s [i] < 256) {
+                       }
+               }
+
+               internal static string HtmlEncode (string s)
+               {
+#if NET_4_0
+                       if (s == null)
+                               return null;
+                       
+                       using (var sw = new StringWriter ()) {
+                               HttpEncoder.Current.HtmlEncode (s, sw);
+                               return sw.ToString ();
+                       }
 #else
-                                       if (s [i] > 159) {
+                       return HttpEncoder.HtmlEncode (s);
 #endif
-                                               output.Append ("&#");
-                                               output.Append (((int) s [i]).ToString (Helpers.InvariantCulture));
-                                               output.Append (";");
-                                       } else {
-                                               output.Append (s [i]);
-                                       }
-                                       break;
-                               }
-                       return output.ToString ();
                }
-       
+               
                /// <summary>
                /// HTML-encodes a string and sends the resulting output to a TextWriter output stream.
                /// </summary>
@@ -1037,8 +530,21 @@ namespace System.Web {
                /// <param name="output">The TextWriter output stream containing the encoded string. </param>
                public static void HtmlEncode(string s, TextWriter output) 
                {
-                       if (s != null)
-                               output.Write (HtmlEncode (s));
+                       if (output == null) {
+#if NET_4_0
+                               throw new ArgumentNullException ("output");
+#else
+                               throw new NullReferenceException (".NET emulation");
+#endif
+                       }
+                               
+                       if (!String.IsNullOrEmpty (s)) {
+#if NET_4_0
+                               HttpEncoder.Current.HtmlEncode (s, output);
+#else
+                               output.Write (HttpEncoder.HtmlEncode (s));
+#endif
+                       }
                }
 #if NET_4_0
                public static string HtmlEncode (object value)
@@ -1125,36 +631,11 @@ namespace System.Web {
 #endif
                public static string UrlPathEncode (string s)
                {
-                       if (s == null || s.Length == 0)
-                               return s;
-
-                       MemoryStream result = new MemoryStream ();
-                       int length = s.Length;
-                       for (int i = 0; i < length; i++) {
-                               UrlPathEncodeChar (s [i], result);
-                       }
-                       return Encoding.ASCII.GetString (result.ToArray ());
-               }
-               
-               static void UrlPathEncodeChar (char c, Stream result)
-               {
-                       if (c < 33 || c > 126) {
-                               byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ());
-                               for (int i = 0; i < bIn.Length; i++) {
-                                       result.WriteByte ((byte) '%');
-                                       int idx = ((int) bIn [i]) >> 4;
-                                       result.WriteByte ((byte) hexChars [idx]);
-                                       idx = ((int) bIn [i]) & 0x0F;
-                                       result.WriteByte ((byte) hexChars [idx]);
-                               }
-                       }
-                       else if (c == ' ') {
-                               result.WriteByte ((byte) '%');
-                               result.WriteByte ((byte) '2');
-                               result.WriteByte ((byte) '0');
-                       }
-                       else
-                               result.WriteByte ((byte) c);
+#if NET_4_0
+                       return HttpEncoder.Current.UrlPathEncode (s);
+#else
+                       return HttpEncoder.UrlPathEncode (s);
+#endif
                }
 
                public static NameValueCollection ParseQueryString (string query)
index bf43926c04a99687b956549089b030118c6e000b..60b3431e1e7f194fde0724461ade6a1978cc2501 100644 (file)
@@ -542,6 +542,7 @@ System.Web.UI.WebControls/WebColorConverterCas.cs
 System.Web.UI.WebControls/WebControlCas.cs
 System.Web.UI.WebControls/XmlCas.cs
 System.Web.UI.WebControls/XmlDataSourceCas.cs
+System.Web.Util/HttpEncoderTest.cs
 System.Web.Util/RequestValidatorTest.cs
 System.Web.Util/TransactionsCas.cs
 System.Web.Util/UrlUtilsTest.cs
diff --git a/mcs/class/System.Web/Test/System.Web.Util/HttpEncoderTest.cs b/mcs/class/System.Web/Test/System.Web.Util/HttpEncoderTest.cs
new file mode 100644 (file)
index 0000000..4975b43
--- /dev/null
@@ -0,0 +1,415 @@
+//
+// Authors:
+//      Marek Habersack <mhabersack@novell.com>
+//
+// Copyright (C) 2010 Novell, Inc. (http://novell.com/)
+//
+// 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.
+//
+#if NET_4_0
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Web;
+using System.Web.Util;
+
+using NUnit.Framework;
+
+using MonoTests.SystemWeb.Framework;
+using MonoTests.stand_alone.WebHarness;
+using MonoTests.Common;
+
+namespace MonoTests.System.Web.Util
+{
+       class HttpEncoderPoker : HttpEncoder
+       {
+               public void CallHtmlAttributeEncode (string value, TextWriter output)
+               {
+                       HtmlAttributeEncode (value, output);
+               }
+
+               public void CallHtmlDecode (string value, TextWriter output)
+               {
+                       HtmlDecode (value, output);
+               }
+
+               public void CallHtmlEncode (string value, TextWriter output)
+               {
+                       HtmlEncode (value, output);
+               }
+
+               public byte [] CallUrlEncode (byte [] bytes, int offset, int count)
+               {
+                       return UrlEncode (bytes, offset, count);
+               }
+
+               public string CallUrlPathEncode (string value)
+               {
+                       return UrlPathEncode (value);
+               }
+
+               public void CallHeaderNameValueEncode (string headerName, string headerValue, out string encodedHeaderName, out string encodedHeaderValue)
+               {
+                       HeaderNameValueEncode (headerName, headerValue, out encodedHeaderName, out encodedHeaderValue);
+               }
+       }
+
+       [TestFixture]
+       public class HttpEncoderTest
+       {
+#if NET_4_0
+               const string notEncoded = "!()*-._";
+#else
+               const string notEncoded = "!'()*-._";
+#endif
+               static char [] hexChars = "0123456789abcdef".ToCharArray ();
+
+               [Test]
+               public void HtmlAttributeEncode ()
+               {
+                       var encoder = new HttpEncoderPoker ();
+                       var sw = new StringWriter ();
+
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               encoder.CallHtmlAttributeEncode ("string", null);
+                       }, "#A1");
+
+                       encoder.CallHtmlAttributeEncode ("<script>", sw);
+                       Assert.AreEqual ("&lt;script>", sw.ToString (), "#A2");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlAttributeEncode ("\"a&b\"", sw);
+                       Assert.AreEqual ("&quot;a&amp;b&quot;", sw.ToString (), "#A3");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlAttributeEncode ("'string'", sw);
+                       Assert.AreEqual ("&#39;string&#39;", sw.ToString (), "#A4");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlAttributeEncode ("\\string\\", sw);
+                       Assert.AreEqual ("\\string\\", sw.ToString (), "#A5");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlAttributeEncode (null, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A6");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlAttributeEncode (null, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A7");
+               }
+
+               [Test]
+               public void HtmlDecode ()
+               {
+                       var encoder = new HttpEncoderPoker ();
+                       StringWriter sw;
+
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               encoder.CallHtmlDecode ("string", null);
+                       }, "#A1");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlDecode (null, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A2");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlDecode (String.Empty, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A3");
+
+                       for (int i = 0; i < decoding_pairs.Length; i += 2) {
+                               sw = new StringWriter ();
+                               encoder.CallHtmlDecode (decoding_pairs [i], sw);
+                               Assert.AreEqual (decoding_pairs [i + 1], sw.ToString (), "#B" + (i / 2).ToString ());
+                       }
+               }
+
+               [Test]
+               public void HtmlDecode_Specials ()
+               {
+                       var encoder = new HttpEncoderPoker ();
+                       var sw = new StringWriter ();
+
+                       encoder.CallHtmlDecode ("&hearts;&#6iQj", sw);
+                       Assert.AreEqual ("♥&#6iQj", sw.ToString (), "#A1");
+               }
+
+               [Test]
+               public void HtmlEncode ()
+               {
+                       var encoder = new HttpEncoderPoker ();
+                       StringWriter sw;
+
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               encoder.CallHtmlEncode ("string", null);
+                       }, "#A1");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlEncode (null, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A2");
+
+                       sw = new StringWriter ();
+                       encoder.CallHtmlEncode (String.Empty, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A3");
+
+                       for (int i = 0; i < encoding_pairs.Length; i += 2) {
+                               sw = new StringWriter ();
+                               encoder.CallHtmlEncode (encoding_pairs [i], sw);
+                               Assert.AreEqual (encoding_pairs [i + 1], sw.ToString (), "#B" + (i / 2).ToString ());
+                       }
+               }
+
+               [Test]
+               public void UrlEncode ()
+               {
+                       var encoder = new HttpEncoderPoker ();
+                       byte [] bytes = new byte [10];
+
+                       AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
+                               encoder.CallUrlEncode (bytes, -1, 1);
+                       }, "#A1-1");
+
+                       AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
+                               encoder.CallUrlEncode (bytes, 11, 1);
+                       }, "#A1-2");
+
+                       AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
+                               encoder.CallUrlEncode (bytes, 0, -1);
+                       }, "#A1-3");
+
+                       AssertExtensions.Throws<ArgumentOutOfRangeException> (() => {
+                               encoder.CallUrlEncode (bytes, 01, 11);
+                       }, "#A1-4");
+
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               encoder.CallUrlEncode (null, 0, 1);
+                       }, "#A1-5");
+
+                       for (char c = char.MinValue; c < char.MaxValue; c++) {
+                               byte [] bIn;
+                               bIn = Encoding.UTF8.GetBytes (c.ToString ());
+                               MemoryStream expected = new MemoryStream ();
+                               MemoryStream expUnicode = new MemoryStream ();
+
+                               //build expected result for UrlEncode
+                               for (int i = 0; i < bIn.Length; i++)
+                                       UrlEncodeChar ((char) bIn [i], expected, false);
+
+                               byte [] expectedBytes = expected.ToArray ();
+                               byte [] encodedBytes = encoder.CallUrlEncode (bIn, 0, bIn.Length);
+                               Assert.IsNotNull (encodedBytes, "#B1-1");
+                               Assert.AreEqual (expectedBytes.Length, encodedBytes.Length, "#B1-2");
+
+                               for (int i = 0; i < expectedBytes.Length; i++)
+                                       Assert.AreEqual (expectedBytes [i], encodedBytes [i], String.Format ("[Char: {0}] [Pos: {1}]", c, i));
+                       }
+
+                       byte [] encoded = encoder.CallUrlEncode (new byte [0], 0, 0);
+                       Assert.IsNotNull (encoded, "#C1-1");
+                       Assert.AreEqual (0, encoded.Length, "#C1-2");
+               }
+
+               static void UrlEncodeChar (char c, Stream result, bool isUnicode)
+               {
+                       if (c > 255) {
+                               //FIXME: what happens when there is an internal error?
+                               //if (!isUnicode)
+                               //      throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
+                               int idx;
+                               int i = (int) c;
+
+                               result.WriteByte ((byte) '%');
+                               result.WriteByte ((byte) 'u');
+                               idx = i >> 12;
+                               result.WriteByte ((byte) hexChars [idx]);
+                               idx = (i >> 8) & 0x0F;
+                               result.WriteByte ((byte) hexChars [idx]);
+                               idx = (i >> 4) & 0x0F;
+                               result.WriteByte ((byte) hexChars [idx]);
+                               idx = i & 0x0F;
+                               result.WriteByte ((byte) hexChars [idx]);
+                               return;
+                       }
+
+                       if (c > ' ' && notEncoded.IndexOf (c) != -1) {
+                               result.WriteByte ((byte) c);
+                               return;
+                       }
+                       if (c == ' ') {
+                               result.WriteByte ((byte) '+');
+                               return;
+                       }
+                       if ((c < '0') ||
+                               (c < 'A' && c > '9') ||
+                               (c > 'Z' && c < 'a') ||
+                               (c > 'z')) {
+                               if (isUnicode && c > 127) {
+                                       result.WriteByte ((byte) '%');
+                                       result.WriteByte ((byte) 'u');
+                                       result.WriteByte ((byte) '0');
+                                       result.WriteByte ((byte) '0');
+                               } else
+                                       result.WriteByte ((byte) '%');
+
+                               int idx = ((int) c) >> 4;
+                               result.WriteByte ((byte) hexChars [idx]);
+                               idx = ((int) c) & 0x0F;
+                               result.WriteByte ((byte) hexChars [idx]);
+                       } else
+                               result.WriteByte ((byte) c);
+               }
+
+               [Test]
+               public void UrlPathEncode ()
+               {
+                       var encoder = new HttpEncoderPoker ();
+
+                       Assert.AreEqual (null, encoder.CallUrlPathEncode (null), "#A1-1");
+                       Assert.AreEqual (String.Empty, encoder.CallUrlPathEncode (String.Empty), "#A1-2");
+
+                       for (char c = char.MinValue; c < char.MaxValue; c++) {
+                               MemoryStream expected = new MemoryStream ();
+                               UrlPathEncodeChar (c, expected);
+
+                               string exp = Encoding.ASCII.GetString (expected.ToArray ());
+                               string act = encoder.CallUrlPathEncode (c.ToString ());
+                               Assert.AreEqual (exp, act, "UrlPathEncode " + c.ToString ());
+                       }
+               }
+
+               [Test]
+               public void UrlPathEncode2 ()
+               {
+                       var encoder = new HttpEncoderPoker ();
+
+                       string s = "default.xxx?sdsd=sds";
+                       string s2 = encoder.CallUrlPathEncode (s);
+                       Assert.AreEqual (s, s2, "UrlPathEncode " + s);
+               }
+
+               static void UrlPathEncodeChar (char c, Stream result)
+               {
+                       if (c < 33 || c > 126) {
+                               byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ());
+                               for (int i = 0; i < bIn.Length; i++) {
+                                       result.WriteByte ((byte) '%');
+                                       int idx = ((int) bIn [i]) >> 4;
+                                       result.WriteByte ((byte) hexChars [idx]);
+                                       idx = ((int) bIn [i]) & 0x0F;
+                                       result.WriteByte ((byte) hexChars [idx]);
+                               }
+                       } else if (c == ' ') {
+                               result.WriteByte ((byte) '%');
+                               result.WriteByte ((byte) '2');
+                               result.WriteByte ((byte) '0');
+                       } else
+                               result.WriteByte ((byte) c);
+               }
+
+               [Test]
+               public void HeaderNameValueEncode ()
+               {
+                       var encoder = new HttpEncoderPoker ();
+                       string encodedName;
+                       string encodedValue;
+                       
+                       encoder.CallHeaderNameValueEncode (null, null, out encodedName, out encodedValue);
+                       Assert.AreEqual (null, encodedName, "#A1-1");
+                       Assert.AreEqual (null, encodedValue, "#A1-2");
+
+                       encoder.CallHeaderNameValueEncode (String.Empty, String.Empty, out encodedName, out encodedValue);
+                       Assert.AreEqual (String.Empty, encodedName, "#A2-1");
+                       Assert.AreEqual (String.Empty, encodedValue, "#A2-2");
+
+                       char ch;
+                       for (int i = Char.MinValue; i <= Char.MaxValue; i++) {
+                               ch = (char) i;
+                               encoder.CallHeaderNameValueEncode (ch.ToString (), null, out encodedName, out encodedValue);
+
+                               if (headerNameEncodedChars.ContainsKey (ch))
+                                       Assert.AreEqual (headerNameEncodedChars [ch], encodedName, "#B1-" + i.ToString ());
+                               else
+                                       Assert.AreEqual (ch.ToString (), encodedName, "#B1-" + i.ToString ());
+
+                               encoder.CallHeaderNameValueEncode (null, ch.ToString (), out encodedName, out encodedValue);
+                               if (headerValueEncodedChars.ContainsKey (ch))
+                                       Assert.AreEqual (headerValueEncodedChars [ch], encodedValue, "#C1-" + i.ToString ());
+                               else
+                                       Assert.AreEqual (ch.ToString (), encodedValue, "#C1-" + i.ToString ());
+                       }
+               }
+
+               Dictionary<char, string> headerNameEncodedChars = new Dictionary<char, string> {
+                       {'\u0000', "%00"}, {'\u0001', "%01"}, {'\u0002', "%02"}, {'\u0003', "%03"}, {'\u0004', "%04"}, 
+                       {'\u0005', "%05"}, {'\u0006', "%06"}, {'\u0007', "%07"}, {'\u0008', "%08"}, {'\u000A', "%0a"}, 
+                       {'\u000B', "%0b"}, {'\u000C', "%0c"}, {'\u000D', "%0d"}, {'\u000E', "%0e"}, {'\u000F', "%0f"}, 
+                       {'\u0010', "%10"}, {'\u0011', "%11"}, {'\u0012', "%12"}, {'\u0013', "%13"}, {'\u0014', "%14"}, 
+                       {'\u0015', "%15"}, {'\u0016', "%16"}, {'\u0017', "%17"}, {'\u0018', "%18"}, {'\u0019', "%19"}, 
+                       {'\u001A', "%1a"}, {'\u001B', "%1b"}, {'\u001C', "%1c"}, {'\u001D', "%1d"}, {'\u001E', "%1e"}, 
+                       {'\u001F', "%1f"}, {'\7f', "%7f"}, 
+               };
+
+               Dictionary<char, string> headerValueEncodedChars = new Dictionary<char, string> {
+                       {'\u0000', "%00"}, {'\u0001', "%01"}, {'\u0002', "%02"}, {'\u0003', "%03"}, {'\u0004', "%04"}, 
+                       {'\u0005', "%05"}, {'\u0006', "%06"}, {'\u0007', "%07"}, {'\u0008', "%08"}, {'\u000A', "%0a"}, 
+                       {'\u000B', "%0b"}, {'\u000C', "%0c"}, {'\u000D', "%0d"}, {'\u000E', "%0e"}, {'\u000F', "%0f"}, 
+                       {'\u0010', "%10"}, {'\u0011', "%11"}, {'\u0012', "%12"}, {'\u0013', "%13"}, {'\u0014', "%14"}, 
+                       {'\u0015', "%15"}, {'\u0016', "%16"}, {'\u0017', "%17"}, {'\u0018', "%18"}, {'\u0019', "%19"}, 
+                       {'\u001A', "%1a"}, {'\u001B', "%1b"}, {'\u001C', "%1c"}, {'\u001D', "%1d"}, {'\u001E', "%1e"}, 
+                       {'\u001F', "%1f"}, {'\7f', "%7f"}, 
+               };
+
+               #region Long arrays of strings
+               string [] decoding_pairs = {
+       @"&aacute;&Aacute;&acirc;&Acirc;&acute;&aelig;&AElig;&agrave;&Agrave;&alefsym;&alpha;&Alpha;&amp;&and;&ang;&aring;&Aring;&asymp;&atilde;&Atilde;&auml;&Auml;&bdquo;&beta;&Beta;&brvbar;&bull;&cap;&ccedil;&Ccedil;&cedil;&cent;&chi;&Chi;&circ;&clubs;&cong;&copy;&crarr;&cup;&curren;&dagger;&Dagger;&darr;&dArr;&deg;&delta;&Delta;&diams;&divide;&eacute;&Eacute;&ecirc;&Ecirc;&egrave;&Egrave;&empty;&emsp;&ensp;&epsilon;&Epsilon;&equiv;&eta;&Eta;&eth;&ETH;&euml;&Euml;&euro;&exist;&fnof;&forall;&frac12;&frac14;&frac34;&frasl;&gamma;&Gamma;&ge;&gt;&harr;&hArr;&hearts;&hellip;&iacute;&Iacute;&icirc;&Icirc;&iexcl;&igrave;&Igrave;&image;&infin;&int;&iota;&Iota;&iquest;&isin;&iuml;&Iuml;&kappa;&Kappa;&lambda;&Lambda;&lang;&laquo;&larr;&lArr;&lceil;&ldquo;&le;&lfloor;&lowast;&loz;&lrm;&lsaquo;&lsquo;&lt;&macr;&mdash;&micro;&middot;&minus;&mu;&Mu;&nabla;&nbsp;&ndash;&ne;&ni;&not;&notin;&nsub;&ntilde;&Ntilde;&nu;&Nu;&oacute;&Oacute;&ocirc;&Ocirc;&oelig;&OElig;&ograve;&Ograve;&oline;&omega;&Omega;&omicron;&Omicron;&oplus;&or;&ordf;&ordm;&oslash;&Oslash;&otilde;&Otilde;&otimes;&ouml;&Ouml;&para;&part;&permil;&perp;&phi;&Phi;&pi;&Pi;&piv;&plusmn;&pound;&prime;&Prime;&prod;&prop;&psi;&Psi;&quot;&radic;&rang;&raquo;&rarr;&rArr;&rceil;&rdquo;&real;&reg;&rfloor;&rho;&Rho;&rlm;&rsaquo;&rsquo;&sbquo;&scaron;&Scaron;&sdot;&sect;&shy;&sigma;&Sigma;&sigmaf;&sim;&spades;&sub;&sube;&sum;&sup;&sup1;&sup2;&sup3;&supe;&szlig;&tau;&Tau;&there4;&theta;&Theta;&thetasym;&thinsp;&thorn;&THORN;&tilde;&times;&trade;&uacute;&Uacute;&uarr;&uArr;&ucirc;&Ucirc;&ugrave;&Ugrave;&uml;&upsih;&upsilon;&Upsilon;&uuml;&Uuml;&weierp;&xi;&Xi;&yacute;&Yacute;&yen;&yuml;&Yuml;&zeta;&Zeta;&zwj;&zwnj;",
+       @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅  εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‎‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ""√〉»→⇒⌉”ℜ®⌋ρΡ‏›’‚šŠ⋅§­σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ‍‌",
+       @"&aacute;?dCO+6Mk'2R&Aacute;T148quH^^=972 &acirc;#&Acirc;js""{1LZz)U&acute;u@Rv-05n L&aelig;3x}&AElig;!&agrave;,=*-J*&Agrave;=P|B&alefsym;Y<g?cg>jB)&alpha;&Alpha;9#4V`)|&J/n&amp;JVK56X\2q*F&and;Js&ang;6k6&aring;""&Aring;?rGt&asymp;\F <9IM{s-&atilde;(ShK&Atilde;w/[%,ksf93'k&auml;+b$@Q{5&Auml;Uo&bdquo;aN~'ycb>VKGcjo&beta;oR8""%B`L&Beta;I7g""k5]A>^B&brvbar;lllUPg5#b&bull;8Pw,bwSiY ""5]a&cap;_R@m&D+Lz""dKLT&ccedil;KH&I}6)_Q&Ccedil;mS%BZV/*Xo&cedil;s5[&cent;-$|)|L&5~&chi;Y/3cdUrn&Chi;8&circ;&)@KU@scEW2I&clubs;p2,US7f>&m!F&cong;Fr9A%,Ci'y[]F+&copy;PY&crarr;FeCrQI<:pPP~;>&cup;&curren;y J#R&%%i&dagger;Ow,&Dagger;T&darr;KpY`WSAo$i:r&dArr;']=&deg;k12&UI@_&delta;(9xD&Delta;dz&diams;RJdB""F^Y}g&divide;2kbZ2>@yBfu&eacute;9!9J(v&Eacute;\TwTS2X5i&ecirc;SLWaTMQE]e&&Ecirc;jW{\#JAh{Ua=&egrave;5&Egrave;6/GY&empty;U&emsp;n:&ensp;dcSf&epsilon;&Epsilon;1Yoi?X&equiv;.-s!n|i9U?3:6&eta;+|6&Eta;ha?>fm!v,&eth;c;Ky]88&ETH;4T@qO#.&euml;@Kl3%&Euml;X-VvUoE& &euro;o9T:r8\||^ha;&exist;1;/BMT*xJ(a>B&fnof;bH'-TH!6NrP&forall;n&frac12;5Fqvq_e9_""XJ&frac14;vmLXTtu:TVZ,&frac34;syl;qEe:b$5j&frasl;b Hg%T&gamma;[&Gamma;H&ge;&gt;{1wT&harr;o6i~jjKC02&hArr;Q4i6m(2tpl&hearts;&#6iQj!&hellip;4le""4} Lv5{Cs&iacute;D*u]j&Iacute;s}#br=&icirc;fh&Icirc;&iexcl;_B:|&igrave;k2U7lZ;_sI\c]&Igrave;s&image; T!5h"".um9ctz&infin; YDL&int;b(S^&iota;bCm&Iota;_L(\-F&iquest;m9g.h$^HSv&isin;cWH#>&iuml;m0&Iuml;KtgRE3c5@0&&kappa;T[2?\>T^H**&Kappa;=^6 [&lambda;um&Lambda;[3wQ5gT?H(Bo\/&lang;6car8P@AjF4e|b&laquo;397jxG:m&larr;U~?~""f&lArr;`O9iwJ#&lceil;L:q-* !V&ldquo;os)Wq6S{t&le;=80A&lfloor;#tS6&lowast;x`g6a>]U-b&loz;SHb/-]&lrm;m9dm""/d<;xR)4&lsaquo;jrb/,q&lsquo;RW}n2shoM11D|&lt;{}*]WPE#d#&macr;&mdash;yhT   k&micro;&middot;`f~o&minus;{Kmf&mu;d7fmt&Mu;PT@OOrzj&nabla;y ;M01XyI:&nbsp;+l<&ndash;x5|a>62y&ne;GNKJQjmj3&ni;Az&not;?V&notin;,<&nsub;R]Lc&ntilde;kV:&Ntilde;9LLf&Z%`d-H^L&nu;v_yXht&Nu;R1yuF!&oacute;j3]zOwQf_YtT9t&Oacute;}s]&1T&ocirc;&Ocirc;2lEN&oelig;:Rp^X+tPNL.&OElig;x0 ?c3ZP&ograve;3&Ograve;&oline;@nE&omega;uK-*HjL-h5z&Omega;~x&omicron;FNQ8D#{&Omicron;Yj|]'LX&oplus;ie-Y&or;&ordf;$*.c&ordm;VM7KQ.b]hmV &oslash;x{R>J-D_0v&Oslash;Hp&otilde;L'IG&Otilde;`&otimes;E &ouml;>KNCm&Ouml;O2dH_&jd^ >2&para;U%""_n&part;U>F&permil;?TSz0~~&perp;!p@G~bH^E&phi;dg)A&Phi; J<<j_,7Q)dEs,&pi;Z&Pi;_B<@%.&?70&piv;9Y^C|VRPrb4}&plusmn;Yn=9=SQ;`}(e%&pound;y;6|RN;|w&prime;AH=XXf&Prime;&prod;DGf6ol&prop;&psi;]UXZU\vzW4&Psi;e`NY[vrvs&quot;xay&radic;[@\scKIznodD<s&rang;PB C)<itm+&raquo;{t-L&rarr;s^^x<:&sh3&rArr;p^s6Y~3Csw=&rceil;_pKnhDNTmA*p&rdquo;]yG6;,ZuPx&real;xsd&reg;`hXlUn~(pK=N:^&rfloor;OS""P{%j-Wjbx.w&rho;ts^&Rho;r$h<:u^&rlm;Vj}\?7SIauBh&rsaquo;u[ !rto/[UHog&rsquo;xe6gY<24BY.&sbquo;`ZNR}&scaron;uY{Gg;F&Scaron;&sdot;az4TlWKYbJ.h&sect;c`9FrP&shy;5_)&sigma;wx.nP}z@&Sigma;NP9-$@j5&sigmaf;&sim;'ogIt:.@Gul&spades;""p\\rH[)&sub;Om/|3G+BQe&sube;5s!f/O9SA\RJkv&sum;GOFMAXu&sup;W&sup1;&sup2;L`r""}u/n&sup3;.ouLC&supe;(f&szlig;{&tau;B%e [&Tau;$DD>kIdV#X`?^\&there4;|S?W&theta;x)2P.![^5&Theta;zqF""pj&thetasym;#BE1u?&thinsp;GGG>(EQE&thorn;!""y1r/&THORN;m&@[\mw[kNR&tilde;|1G#i[(&times;X<UotTID uY&trade;sWW+TbxY&uacute;kQXr!H6&Uacute;~0TiH1POP&uarr;(CRZttz\EY<&uArr;&bN7ki|&ucirc;r,3j!e$kJE&Z$z&Ucirc;5{0[bvD""[<P)&ugrave;;1EeRSrz/gY/&Ugrave;/1 S`I*q8:Z-&uml;%N)W&upsih;O[2P9 ?&upsilon;O&Upsilon;t&uuml;&Uuml;VLq&weierp;2""(Z'~~""uiX&xi;NCq&Xi;9)S]^v 3&yacute;x""|2&$`G&Yacute;<&Nr&yen;[3NB5f&yuml; c""MzMw3(;""s&Yuml;&zeta;{!&Zeta;oevp1'j(E`vJ&zwj;Si&zwnj;gw>yc*U",
+       @"á?dCO+6Mk'2RÁT148quH^^=972 â#Âjs""{1LZz)U´u@Rv-05n Læ3x}Æ!à,=*-J*À=P|BℵY<g?cg>jB)αΑ9#4V`)|&J/n&JVK56X\2q*F∧Js∠6k6å""Å?rGt≈\F <9IM{s-ã(ShKÃw/[%,ksf93'kä+b$@Q{5ÄUo„aN~'ycb>VKGcjoβoR8""%B`LΒI7g""k5]A>^B¦lllUPg5#b•8Pw,bwSiY ""5]a∩_R@m&D+Lz""dKLTçKH&I}6)_QÇmS%BZV/*Xo¸s5[¢-$|)|L&5~χY/3cdUrnΧ8ˆ&)@KU@scEW2I♣p2,US7f>&m!F≅Fr9A%,Ci'y[]F+©PY↵FeCrQI<:pPP~;>∪¤y J#R&%%i†Ow,‡T↓KpY`WSAo$i:r⇓']=°k12&UI@_δ(9xDΔdz♦RJdB""F^Y}g÷2kbZ2>@yBfué9!9J(vÉ\TwTS2X5iêSLWaTMQE]e&ÊjW{\#JAh{Ua=è5È6/GY∅U n: dcSfεΕ1Yoi?X≡.-s!n|i9U?3:6η+|6Ηha?>fm!v,ðc;Ky]88Ð4T@qO#.ë@Kl3%ËX-VvUoE& €o9T:r8\||^ha;∃1;/BMT*xJ(a>BƒbH'-TH!6NrP∀n½5Fqvq_e9_""XJ¼vmLXTtu:TVZ,¾syl;qEe:b$5j⁄b Hg%Tγ[ΓH≥>{1wT↔o6i~jjKC02⇔Q4i6m(2tpl♥&#6iQj!…4le""4} Lv5{CsíD*u]jÍs}#br=îfhΡ_B:|ìk2U7lZ;_sI\c]Ìsℑ T!5h"".um9ctz∞ YDL∫b(S^ιbCmΙ_L(\-F¿m9g.h$^HSv∈cWH#>ïm0ÏKtgRE3c5@0&κT[2?\>T^H**Κ=^6 [λumΛ[3wQ5gT?H(Bo\/〈6car8P@AjF4e|b«397jxG:m←U~?~""f⇐`O9iwJ#⌈L:q-* !V“os)Wq6S{t≤=80A⌊#tS6∗x`g6a>]U-b◊SHb/-]‎m9dm""/d<;xR)4‹jrb/,q‘RW}n2shoM11D|<{}*]WPE#d#¯—yhT   kµ·`f~o−{Kmfμd7fmtΜPT@OOrzj∇y ;M01XyI: +l<–x5|a>62y≠GNKJQjmj3∋Az¬?V∉,<⊄R]LcñkV:Ñ9LLf&Z%`d-H^Lνv_yXhtΝR1yuF!ój3]zOwQf_YtT9tÓ}s]&1TôÔ2lENœ:Rp^X+tPNL.Œx0 ?c3ZPò3Ò‾@nEωuK-*HjL-h5zΩ~xοFNQ8D#{ΟYj|]'LX⊕ie-Y∨ª$*.cºVM7KQ.b]hmV øx{R>J-D_0vØHpõL'IGÕ`⊗E ö>KNCmÖO2dH_&jd^ >2¶U%""_n∂U>F‰?TSz0~~⊥!p@G~bH^Eφdg)AΦ J<<j_,7Q)dEs,πZΠ_B<@%.&?70ϖ9Y^C|VRPrb4}±Yn=9=SQ;`}(e%£y;6|RN;|w′AH=XXf″∏DGf6ol∝ψ]UXZU\vzW4Ψe`NY[vrvs""xay√[@\scKIznodD<s〉PB C)<itm+»{t-L→s^^x<:&sh3⇒p^s6Y~3Csw=⌉_pKnhDNTmA*p”]yG6;,ZuPxℜxsd®`hXlUn~(pK=N:^⌋OS""P{%j-Wjbx.wρts^Ρr$h<:u^‏Vj}\?7SIauBh›u[ !rto/[UHog’xe6gY<24BY.‚`ZNR}šuY{Gg;FŠ⋅az4TlWKYbJ.h§c`9FrP­5_)σwx.nP}z@ΣNP9-$@j5ς∼'ogIt:.@Gul♠""p\\rH[)⊂Om/|3G+BQe⊆5s!f/O9SA\RJkv∑GOFMAXu⊃W¹²L`r""}u/n³.ouLC⊇(fß{τB%e [Τ$DD>kIdV#X`?^\∴|S?Wθx)2P.![^5ΘzqF""pjϑ#BE1u? GGG>(EQEþ!""y1r/Þm&@[\mw[kNR˜|1G#i[(×X<UotTID uY™sWW+TbxYúkQXr!H6Ú~0TiH1POP↑(CRZttz\EY<⇑&bN7ki|ûr,3j!e$kJE&Z$zÛ5{0[bvD""[<P)ù;1EeRSrz/gY/Ù/1 S`I*q8:Z-¨%N)WϒO[2P9 ?υOΥtüÜVLq℘2""(Z'~~""uiXξNCqΞ9)S]^v 3ýx""|2&$`GÝ<&Nr¥[3NB5fÿ c""MzMw3(;""sŸζ{!Ζoevp1'j(E`vJ‍Si‌gw>yc*U",
+       @"&aacute&Aacute&acirc&Acirc&acute&aelig&AElig&agrave&Agrave&alefsym&alpha&Alpha&amp&and&ang&aring&Aring&asymp&atilde&Atilde&auml&Auml&bdquo&beta&Beta&brvbar&bull&cap&ccedil&Ccedil&cedil&cent&chi&Chi&circ&clubs&cong&copy&crarr&cup&curren&dagger&Dagger&darr&dArr&deg&delta&Delta&diams&divide&eacute&Eacute&ecirc&Ecirc&egrave&Egrave&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&Eta&eth&ETH&euml&Euml&euro&exist&fnof&forall&frac12&frac14&frac34&frasl&gamma&Gamma&ge&gt&harr&hArr&hearts&hellip&iacute&Iacute&icirc&Icirc&iexcl&igrave&Igrave&image&infin&int&iota&Iota&iquest&isin&iuml&Iuml&kappa&Kappa&lambda&Lambda&lang&laquo&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo&lt&macr&mdash&micro&middot&minus&mu&Mu&nabla&nbsp&ndash&ne&ni&not&notin&nsub&ntilde&Ntilde&nu&Nu&oacute&Oacute&ocirc&Ocirc&oelig&OElig&ograve&Ograve&oline&omega&Omega&omicron&Omicron&oplus&or&ordf&ordm&oslash&Oslash&otilde&Otilde&otimes&ouml&Ouml&para&part&permil&perp&phi&Phi&pi&Pi&piv&plusmn&pound&prime&Prime&prod&prop&psi&Psi&quot&radic&rang&raquo&rarr&rArr&rceil&rdquo&real&reg&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot&sect&shy&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup&sup1&sup2&sup3&supe&szlig&tau&Tau&there4&theta&Theta&thetasym&thinsp&thorn&THORN&tilde&times&trade&uacute&Uacute&uarr&uArr&ucirc&Ucirc&ugrave&Ugrave&uml&upsih&upsilon&Upsilon&uuml&Uuml&weierp&xi&Xi&yacute&Yacute&yen&yuml&Yuml&zeta&Zeta&zwj&zwnj",
+       @"&aacute&Aacute&acirc&Acirc&acute&aelig&AElig&agrave&Agrave&alefsym&alpha&Alpha&amp&and&ang&aring&Aring&asymp&atilde&Atilde&auml&Auml&bdquo&beta&Beta&brvbar&bull&cap&ccedil&Ccedil&cedil&cent&chi&Chi&circ&clubs&cong&copy&crarr&cup&curren&dagger&Dagger&darr&dArr&deg&delta&Delta&diams&divide&eacute&Eacute&ecirc&Ecirc&egrave&Egrave&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&Eta&eth&ETH&euml&Euml&euro&exist&fnof&forall&frac12&frac14&frac34&frasl&gamma&Gamma&ge&gt&harr&hArr&hearts&hellip&iacute&Iacute&icirc&Icirc&iexcl&igrave&Igrave&image&infin&int&iota&Iota&iquest&isin&iuml&Iuml&kappa&Kappa&lambda&Lambda&lang&laquo&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo&lt&macr&mdash&micro&middot&minus&mu&Mu&nabla&nbsp&ndash&ne&ni&not&notin&nsub&ntilde&Ntilde&nu&Nu&oacute&Oacute&ocirc&Ocirc&oelig&OElig&ograve&Ograve&oline&omega&Omega&omicron&Omicron&oplus&or&ordf&ordm&oslash&Oslash&otilde&Otilde&otimes&ouml&Ouml&para&part&permil&perp&phi&Phi&pi&Pi&piv&plusmn&pound&prime&Prime&prod&prop&psi&Psi&quot&radic&rang&raquo&rarr&rArr&rceil&rdquo&real&reg&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot&sect&shy&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup&sup1&sup2&sup3&supe&szlig&tau&Tau&there4&theta&Theta&thetasym&thinsp&thorn&THORN&tilde&times&trade&uacute&Uacute&uarr&uArr&ucirc&Ucirc&ugrave&Ugrave&uml&upsih&upsilon&Upsilon&uuml&Uuml&weierp&xi&Xi&yacute&Yacute&yen&yuml&Yuml&zeta&Zeta&zwj&zwnj",
+       @"&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;&#176;&#177;&#178;&#179;&#180;&#181;&#182;&#183;&#184;&#185;&#186;&#187;&#188;&#189;&#190;&#191;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#215;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#247;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;",
+       @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
+       @"&#000;&#001;&#002;&#003;&#004;&#005;&#006;&#007;&#008;&#009;&#010;&#011;&#012;&#013;&#014;&#015;&#016;&#017;&#018;&#019;&#020;&#021;&#022;&#023;&#024;&#025;&#026;&#027;&#028;&#029;&#030;&#031;&#032;",
+       "&#000;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       @"&#x00;&#x01;&#x02;&#x03;&#x04;&#x05;&#x06;&#x07;&#x08;&#x09;&#x0A;&#x0B;&#x0C;&#x0D;&#x0E;&#x0F;&#x10;&#x11;&#x12;&#x13;&#x14;&#x15;&#x16;&#x17;&#x18;&#x19;&#x1A;&#x1B;&#x1C;&#x1D;&#x1E;&#x1F;&#x20;",
+       "&#x00;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       @"&#xA0;&#xA1;&#xA2;&#xA3;&#xA4;&#xA5;&#xA6;&#xA7;&#xA8;&#xA9;&#xAA;&#xAB;&#xAC;&#xAD;&#xAE;&#xAF;&#xB0;&#xB1;&#xB2;&#xB3;&#xB4;&#xB5;&#xB6;&#xB7;&#xB8;&#xB9;&#xBA;&#xBB;&#xBC;&#xBD;&#xBE;&#xBF;&#xC0;&#xC1;&#xC2;&#xC3;&#xC4;&#xC5;&#xC6;&#xC7;&#xC8;&#xC9;&#xCA;&#xCB;&#xCC;&#xCD;&#xCE;&#xCF;&#xD0;&#xD1;&#xD2;&#xD3;&#xD4;&#xD5;&#xD6;&#xD7;&#xD8;&#xD9;&#xDA;&#xDB;&#xDC;&#xDD;&#xDE;&#xDF;&#xE0;&#xE1;&#xE2;&#xE3;&#xE4;&#xE5;&#xE6;&#xE7;&#xE8;&#xE9;&#xEA;&#xEB;&#xEC;&#xED;&#xEE;&#xEF;&#xF0;&#xF1;&#xF2;&#xF3;&#xF4;&#xF5;&#xF6;&#xF7;&#xF8;&#xF9;&#xFA;&#xFB;&#xFC;&#xFD;&#xFE;&#xFF;",
+       " ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
+};
+               string [] encoding_pairs = {
+       @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅  εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‎‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ""√〉»→⇒⌉”ℜ®⌋ρΡ‏›’‚šŠ⋅§­σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ‍‌",
+       @"&#225;&#193;&#226;&#194;&#180;&#230;&#198;&#224;&#192;ℵαΑ&amp;∧∠&#229;&#197;≈&#227;&#195;&#228;&#196;„βΒ&#166;•∩&#231;&#199;&#184;&#162;χΧˆ♣≅&#169;↵∪&#164;†‡↓⇓&#176;δΔ♦&#247;&#233;&#201;&#234;&#202;&#232;&#200;∅  εΕ≡ηΗ&#240;&#208;&#235;&#203;€∃ƒ∀&#189;&#188;&#190;⁄γΓ≥&gt;↔⇔♥…&#237;&#205;&#238;&#206;&#161;&#236;&#204;ℑ∞∫ιΙ&#191;∈&#239;&#207;κΚλΛ〈&#171;←⇐⌈“≤⌊∗◊‎‹‘&lt;&#175;—&#181;&#183;−μΜ∇&#160;–≠∋&#172;∉⊄&#241;&#209;νΝ&#243;&#211;&#244;&#212;œŒ&#242;&#210;‾ωΩοΟ⊕∨&#170;&#186;&#248;&#216;&#245;&#213;⊗&#246;&#214;&#182;∂‰⊥φΦπΠϖ&#177;&#163;′″∏∝ψΨ&quot;√〉&#187;→⇒⌉”ℜ&#174;⌋ρΡ‏›’‚šŠ⋅&#167;&#173;σΣς∼♠⊂⊆∑⊃&#185;&#178;&#179;⊇&#223;τΤ∴θΘϑ &#254;&#222;˜&#215;™&#250;&#218;↑⇑&#251;&#219;&#249;&#217;&#168;ϒυΥ&#252;&#220;℘ξΞ&#253;&#221;&#165;&#255;ŸζΖ‍‌",
+       @"á9cP!qdO#hU@mg1ÁK%0<}*âÂ5[Y;lfMQ$4`´uim7E`%_1zVDkæ[cM{Æt9y:E8Hb;;$;Y'àUa6wÀ<$@W9$4NL*h#'ℵk\zαG}{}hC-Α|=QhyLT%`&wB!@#x51R 4C∧]Z3n∠y>:{JZ'v|c0;N""åzcWM'z""gÅo-JX!r.e≈Z+BT{wF8+ãQ 6P1o?x""ef}vUÃ+</Nt)TI]sä0Eg_'mn&6WY[8Äay+ u[3kqoZ„i6rβUX\:_y1A^x.p>+Β`uf3/HI¦7bCRv%o$X3:•∩ç|(fgiA|MBLf=y@Ǹ¢R,qDW;F9<mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(©7DZ`1>r~.↵4B&R∪+x2T`q[M-lq'¤~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr>74~yHB=&EI⇓,u@Jx°δcC`2,Δo2B]6PP8♦|{!wZa&,*N'$6÷-{nVSgO]%(Ié6Éêosx-2xDI!Ê_]7Ub%èYG4`Gx{ÈH>vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6TðT!Z:Nq_0797;!Ð4]QNë9+>x9>nm-s8YËwZ}vY€:HHf∃;=0,?ƒIr`I:i5'∀z_$Q<½_sCF;=$43DpDz]¼.aMTIEwx\ogn7A¾CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV>↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Okíjt$NKbGrÍ""+alp<îRÎ%¡yìz2 AÌ-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ¿6qqb0|BQ$H%p+d∈.Wa=YBfS'd-EOïISG+=W;GHÏ3||b-icT""qAκ*/ΚλN>j}""WrqΛt]dm-Xe/v〈\«$F< X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8[""3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO‎&-L>DsUej‹C[n]Q<%UoyO‘?zUgpr+62sY<T{7n*^¯4CH]6^e/x/—uT->mQh\""µZSTN!F(U%5·17:Cu<−)*c2μTΜ%:6-e&L[ Xos/4∇]Xr 1c=qyv4HSw~HL~–{+qG?/}≠6`S"",+pL∋>¬B9∉G;6P]xc 0Bs⊄7,j0Sj2/&ñFsÑ=νKs*?[54bV1ΝQ%p6P0.Lrc`yóA/*`6sBH?67Ó&ôÔI""Hœ~e9Œ>oò5eZI}iy?}KÒS‾anD1nXωIΩu""ο:Mz$(""joU^[mΟ7M1f$j>N|Q/@(⊕de6(∨WXb<~;tI?bt#ªU:º+wb(*cA=øjb c%*?Uj6<T02Ø/A}j'MõjlfYlR~er7D@3WÕe:XTLF?|""yd7x⊗eV6Mmw2{K<lö%B%/o~r9Öc1Q TJnd^¶;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv±TAvFo+;JE,2?£""'6F9fRp′,0″<∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e>S~kO""'4""/i4\>!]H;T^0o√8_G`*8&An\rhc)〉&UEk»-(YtC→(zerUTMTe,'@{⇒mlzVhU<S,5}9DM⌉/%R=10*[{'=:”C0ℜ4HoT?-#+l[SnPs®0 bV⌋TρΡjb1}OJ:,0z6‏oTxP""""FOT[;›'’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&u§= _CqlY1O'­qNf|&σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D¹KVO²%:~Iq?IUcHr4y³QP@R't!⊇vßYnI@FXxT<τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR  %`g|*8DECþ_[Þ'8,?˜}gnaz_U×-F^™9ZDO86ú]y\ecHQSÚk-07/AT|0Ce↑F⇑*}e|r$6ln!V`ûA!*8H,mÛ~6G6w&GùsPL6ÙQ¨}J^NO}=._Mnϒ{&υ=ΥWD+f>fy|nNyP*Jüo8,lh\ÜN`'g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=Sý9tI_Ý}p(D51=X¥cH8L)$*]~=IÿdbŸf>J^1Dnζ@(drH;91?{6`xJΖ4N4[u+5‍9.W\v‌]GGtKvCC0`A",
+       @"&#225;9cP!qdO#hU@mg1&#193;K%0&lt;}*&#226;&#194;5[Y;lfMQ$4`&#180;uim7E`%_1zVDk&#230;[cM{&#198;t9y:E8Hb;;$;Y&#39;&#224;Ua6w&#192;&lt;$@W9$4NL*h#&#39;ℵk\zαG}{}hC-Α|=QhyLT%`&amp;wB!@#x51R 4C∧]Z3n∠y&gt;:{JZ&#39;v|c0;N&quot;&#229;zcWM&#39;z&quot;g&#197;o-JX!r.e≈Z+BT{wF8+&#227;Q 6P1o?x&quot;ef}vU&#195;+&lt;/Nt)TI]s&#228;0Eg_&#39;mn&amp;6WY[8&#196;ay+ u[3kqoZ„i6rβUX\:_y1A^x.p&gt;+Β`uf3/HI&#166;7bCRv%o$X3:•∩&#231;|(fgiA|MBLf=y@&#199;&#184;&#162;R,qDW;F9&lt;mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(&#169;7DZ`1&gt;r~.↵4B&amp;R∪+x2T`q[M-lq&#39;&#164;~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr&gt;74~yHB=&amp;EI⇓,u@Jx&#176;δcC`2,Δo2B]6PP8♦|{!wZa&amp;,*N&#39;$6&#247;-{nVSgO]%(I&#233;6&#201;&#234;osx-2xDI!&#202;_]7Ub%&#232;YG4`Gx{&#200;H&gt;vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6T&#240;T!Z:Nq_0797;!&#208;4]QN&#235;9+&gt;x9&gt;nm-s8Y&#203;wZ}vY€:HHf∃;=0,?ƒIr`I:i5&#39;∀z_$Q&lt;&#189;_sCF;=$43DpDz]&#188;.aMTIEwx\ogn7A&#190;CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV&gt;↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Ok&#237;jt$NKbGr&#205;&quot;+alp&lt;&#238;R&#206;%&#161;y&#236;z2 A&#204;-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ&#191;6qqb0|BQ$H%p+d∈.Wa=YBfS&#39;d-EO&#239;ISG+=W;GH&#207;3||b-icT&quot;qAκ*/ΚλN&gt;j}&quot;WrqΛt]dm-Xe/v〈\&#171;$F&lt; X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8[&quot;3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO‎&amp;-L&gt;DsUej‹C[n]Q&lt;%UoyO‘?zUgpr+62sY&lt;T{7n*^&#175;4CH]6^e/x/—uT-&gt;mQh\&quot;&#181;ZSTN!F(U%5&#183;17:Cu&lt;−)*c2μTΜ%:6-e&amp;L[ Xos/4∇]Xr&#160;1c=qyv4HSw~HL~–{+qG?/}≠6`S&quot;,+pL∋&gt;&#172;B9∉G;6P]xc 0Bs⊄7,j0Sj2/&amp;&#241;Fs&#209;=νKs*?[54bV1ΝQ%p6P0.Lrc`y&#243;A/*`6sBH?67&#211;&amp;&#244;&#212;I&quot;Hœ~e9Œ&gt;o&#242;5eZI}iy?}K&#210;S‾anD1nXωIΩu&quot;ο:Mz$(&quot;joU^[mΟ7M1f$j&gt;N|Q/@(⊕de6(∨WXb&lt;~;tI?bt#&#170;U:&#186;+wb(*cA=&#248;jb c%*?Uj6&lt;T02&#216;/A}j&#39;M&#245;jlfYlR~er7D@3W&#213;e:XTLF?|&quot;yd7x⊗eV6Mmw2{K&lt;l&#246;%B%/o~r9&#214;c1Q TJnd^&#182;;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv&#177;TAvFo+;JE,2?&#163;&quot;&#39;6F9fRp′,0″&lt;∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e&gt;S~kO&quot;&#39;4&quot;/i4\&gt;!]H;T^0o√8_G`*8&amp;An\rhc)〉&amp;UEk&#187;-(YtC→(zerUTMTe,&#39;@{⇒mlzVhU&lt;S,5}9DM⌉/%R=10*[{&#39;=:”C0ℜ4HoT?-#+l[SnPs&#174;0 bV⌋TρΡjb1}OJ:,0z6‏oTxP&quot;&quot;FOT[;›&#39;’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&amp;u&#167;= _CqlY1O&#39;&#173;qNf|&amp;σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D&#185;KVO&#178;%:~Iq?IUcHr4y&#179;QP@R&#39;t!⊇v&#223;YnI@FXxT&lt;τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR  %`g|*8DEC&#254;_[&#222;&#39;8,?˜}gnaz_U&#215;-F^™9ZDO86&#250;]y\ecHQS&#218;k-07/AT|0Ce↑F⇑*}e|r$6ln!V`&#251;A!*8H,m&#219;~6G6w&amp;G&#249;sPL6&#217;Q&#168;}J^NO}=._Mnϒ{&amp;υ=ΥWD+f&gt;fy|nNyP*J&#252;o8,lh\&#220;N`&#39;g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=S&#253;9tI_&#221;}p(D51=X&#165;cH8L)$*]~=I&#255;dbŸf&gt;J^1Dnζ@(drH;91?{6`xJΖ4N4[u+5‍9.W\v‌]GGtKvCC0`A",
+       @"&aacute&Aacute&acirc&Acirc&acute&aelig&AElig&agrave&Agrave&alefsym&alpha&Alpha&amp&and&ang&aring&Aring&asymp&atilde&Atilde&auml&Auml&bdquo&beta&Beta&brvbar&bull&cap&ccedil&Ccedil&cedil&cent&chi&Chi&circ&clubs&cong&copy&crarr&cup&curren&dagger&Dagger&darr&dArr&deg&delta&Delta&diams&divide&eacute&Eacute&ecirc&Ecirc&egrave&Egrave&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&Eta&eth&ETH&euml&Euml&euro&exist&fnof&forall&frac12&frac14&frac34&frasl&gamma&Gamma&ge&gt&harr&hArr&hearts&hellip&iacute&Iacute&icirc&Icirc&iexcl&igrave&Igrave&image&infin&int&iota&Iota&iquest&isin&iuml&Iuml&kappa&Kappa&lambda&Lambda&lang&laquo&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo&lt&macr&mdash&micro&middot&minus&mu&Mu&nabla&nbsp&ndash&ne&ni&not&notin&nsub&ntilde&Ntilde&nu&Nu&oacute&Oacute&ocirc&Ocirc&oelig&OElig&ograve&Ograve&oline&omega&Omega&omicron&Omicron&oplus&or&ordf&ordm&oslash&Oslash&otilde&Otilde&otimes&ouml&Ouml&para&part&permil&perp&phi&Phi&pi&Pi&piv&plusmn&pound&prime&Prime&prod&prop&psi&Psi&quot&radic&rang&raquo&rarr&rArr&rceil&rdquo&real&reg&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot&sect&shy&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup&sup1&sup2&sup3&supe&szlig&tau&Tau&there4&theta&Theta&thetasym&thinsp&thorn&THORN&tilde&times&trade&uacute&Uacute&uarr&uArr&ucirc&Ucirc&ugrave&Ugrave&uml&upsih&upsilon&Upsilon&uuml&Uuml&weierp&xi&Xi&yacute&Yacute&yen&yuml&Yuml&zeta&Zeta&zwj&zwnj",
+       @"&amp;aacute&amp;Aacute&amp;acirc&amp;Acirc&amp;acute&amp;aelig&amp;AElig&amp;agrave&amp;Agrave&amp;alefsym&amp;alpha&amp;Alpha&amp;amp&amp;and&amp;ang&amp;aring&amp;Aring&amp;asymp&amp;atilde&amp;Atilde&amp;auml&amp;Auml&amp;bdquo&amp;beta&amp;Beta&amp;brvbar&amp;bull&amp;cap&amp;ccedil&amp;Ccedil&amp;cedil&amp;cent&amp;chi&amp;Chi&amp;circ&amp;clubs&amp;cong&amp;copy&amp;crarr&amp;cup&amp;curren&amp;dagger&amp;Dagger&amp;darr&amp;dArr&amp;deg&amp;delta&amp;Delta&amp;diams&amp;divide&amp;eacute&amp;Eacute&amp;ecirc&amp;Ecirc&amp;egrave&amp;Egrave&amp;empty&amp;emsp&amp;ensp&amp;epsilon&amp;Epsilon&amp;equiv&amp;eta&amp;Eta&amp;eth&amp;ETH&amp;euml&amp;Euml&amp;euro&amp;exist&amp;fnof&amp;forall&amp;frac12&amp;frac14&amp;frac34&amp;frasl&amp;gamma&amp;Gamma&amp;ge&amp;gt&amp;harr&amp;hArr&amp;hearts&amp;hellip&amp;iacute&amp;Iacute&amp;icirc&amp;Icirc&amp;iexcl&amp;igrave&amp;Igrave&amp;image&amp;infin&amp;int&amp;iota&amp;Iota&amp;iquest&amp;isin&amp;iuml&amp;Iuml&amp;kappa&amp;Kappa&amp;lambda&amp;Lambda&amp;lang&amp;laquo&amp;larr&amp;lArr&amp;lceil&amp;ldquo&amp;le&amp;lfloor&amp;lowast&amp;loz&amp;lrm&amp;lsaquo&amp;lsquo&amp;lt&amp;macr&amp;mdash&amp;micro&amp;middot&amp;minus&amp;mu&amp;Mu&amp;nabla&amp;nbsp&amp;ndash&amp;ne&amp;ni&amp;not&amp;notin&amp;nsub&amp;ntilde&amp;Ntilde&amp;nu&amp;Nu&amp;oacute&amp;Oacute&amp;ocirc&amp;Ocirc&amp;oelig&amp;OElig&amp;ograve&amp;Ograve&amp;oline&amp;omega&amp;Omega&amp;omicron&amp;Omicron&amp;oplus&amp;or&amp;ordf&amp;ordm&amp;oslash&amp;Oslash&amp;otilde&amp;Otilde&amp;otimes&amp;ouml&amp;Ouml&amp;para&amp;part&amp;permil&amp;perp&amp;phi&amp;Phi&amp;pi&amp;Pi&amp;piv&amp;plusmn&amp;pound&amp;prime&amp;Prime&amp;prod&amp;prop&amp;psi&amp;Psi&amp;quot&amp;radic&amp;rang&amp;raquo&amp;rarr&amp;rArr&amp;rceil&amp;rdquo&amp;real&amp;reg&amp;rfloor&amp;rho&amp;Rho&amp;rlm&amp;rsaquo&amp;rsquo&amp;sbquo&amp;scaron&amp;Scaron&amp;sdot&amp;sect&amp;shy&amp;sigma&amp;Sigma&amp;sigmaf&amp;sim&amp;spades&amp;sub&amp;sube&amp;sum&amp;sup&amp;sup1&amp;sup2&amp;sup3&amp;supe&amp;szlig&amp;tau&amp;Tau&amp;there4&amp;theta&amp;Theta&amp;thetasym&amp;thinsp&amp;thorn&amp;THORN&amp;tilde&amp;times&amp;trade&amp;uacute&amp;Uacute&amp;uarr&amp;uArr&amp;ucirc&amp;Ucirc&amp;ugrave&amp;Ugrave&amp;uml&amp;upsih&amp;upsilon&amp;Upsilon&amp;uuml&amp;Uuml&amp;weierp&amp;xi&amp;Xi&amp;yacute&amp;Yacute&amp;yen&amp;yuml&amp;Yuml&amp;zeta&amp;Zeta&amp;zwj&amp;zwnj",
+       @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
+       @"&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;&#176;&#177;&#178;&#179;&#180;&#181;&#182;&#183;&#184;&#185;&#186;&#187;&#188;&#189;&#190;&#191;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#215;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#247;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;",
+       "&#000;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       "&amp;#000;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       "&#x00;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       "&amp;#x00;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
+       @"&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;&#176;&#177;&#178;&#179;&#180;&#181;&#182;&#183;&#184;&#185;&#186;&#187;&#188;&#189;&#190;&#191;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#215;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#247;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;",
+};
+               #endregion
+       }
+}
+#endif
\ No newline at end of file
index 013864057db6f82e30247d057efd5f2e6700449b..2b42c92dd3a818df80074280855ad0d4d6fc66cb 100644 (file)
@@ -33,24 +33,108 @@ using System.IO;
 using System.Collections.Specialized;
 
 using NUnit.Framework;
+using MonoTests.Common;
 
 namespace MonoTests.System.Web {
 
        [TestFixture]
-       public class HttpUtilityTest {
+       public class HttpUtilityTest
+       {
 
                [Test]
                public void HtmlAttributeEncode ()
                {
-                       Assert.AreEqual ("&lt;script>", HttpUtility.HtmlAttributeEncode ("<script>"));
-                       Assert.AreEqual ("&quot;a&amp;b&quot;", HttpUtility.HtmlAttributeEncode ("\"a&b\""));
+                       Assert.AreEqual (null, HttpUtility.HtmlAttributeEncode (null), "#A1");
+                       Assert.AreEqual (String.Empty, HttpUtility.HtmlAttributeEncode (String.Empty), "#A2");
+                       Assert.AreEqual ("&lt;script>", HttpUtility.HtmlAttributeEncode ("<script>"), "#A3");
+                       Assert.AreEqual ("&quot;a&amp;b&quot;", HttpUtility.HtmlAttributeEncode ("\"a&b\""), "#A4");
 #if NET_4_0
-                       Assert.AreEqual ("&#39;string&#39;", HttpUtility.HtmlAttributeEncode ("'string'"));
+                       Assert.AreEqual ("&#39;string&#39;", HttpUtility.HtmlAttributeEncode ("'string'"), "#A5");
 #else
-                       Assert.AreEqual ("'string'", HttpUtility.HtmlAttributeEncode ("'string'"));
+                       Assert.AreEqual ("'string'", HttpUtility.HtmlAttributeEncode ("'string'"), "#A5");
 #endif
                }
 
+               [Test]
+               public void HtmlAttributeEncode_String_TextWriter ()
+               {
+                       var sw = new StringWriter ();
+#if NET_4_0
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               HttpUtility.HtmlAttributeEncode ("string", null);
+                       }, "#A1");
+#else
+                       AssertExtensions.Throws<NullReferenceException> (() => {
+                               HttpUtility.HtmlAttributeEncode ("string", null);
+                       }, "#A1");
+#endif
+
+                       HttpUtility.HtmlAttributeEncode ("<script>", sw);
+                       Assert.AreEqual ("&lt;script>", sw.ToString (), "#A2");
+
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlAttributeEncode ("\"a&b\"", sw);
+                       Assert.AreEqual ("&quot;a&amp;b&quot;", sw.ToString (), "#A3");
+
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlAttributeEncode ("'string'", sw);
+#if NET_4_0
+                       Assert.AreEqual ("&#39;string&#39;", sw.ToString (), "#A4");
+#else
+                       Assert.AreEqual ("'string'", sw.ToString (), "#A4");
+#endif
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlAttributeEncode ("\\string\\", sw);
+                       Assert.AreEqual ("\\string\\", sw.ToString (), "#A5");
+
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlAttributeEncode (String.Empty, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A6");
+
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlAttributeEncode (null, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A7");
+               }
+
+               [Test]
+               public void HtmlDecode ()
+               {
+                       Assert.AreEqual (null, HttpUtility.HtmlDecode (null), "#A1");
+                       Assert.AreEqual (String.Empty, HttpUtility.HtmlDecode (String.Empty), "#A2");
+
+                       for (int i = 0; i < decoding_pairs.Length; i += 2)
+                               Assert.AreEqual (decoding_pairs [i + 1], HttpUtility.HtmlDecode (decoding_pairs [i]), "#B" + (i / 2).ToString ());
+               }
+
+               [Test]
+               public void HtmlDecode_String_TextWriter ()
+               {
+                       StringWriter sw;
+#if NET_4_0
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               HttpUtility.HtmlDecode ("string", null);
+                       }, "#A1");
+#else
+                       AssertExtensions.Throws<NullReferenceException> (() => {
+                               HttpUtility.HtmlDecode ("string", null);
+                       }, "#A1");
+#endif
+
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlDecode (null, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A2");
+
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlDecode (String.Empty, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A3");
+
+                       for (int i = 0; i < decoding_pairs.Length; i += 2) {
+                               sw = new StringWriter ();
+                               HttpUtility.HtmlDecode (decoding_pairs [i], sw);
+                               Assert.AreEqual (decoding_pairs [i + 1], sw.ToString (), "#B" + (i / 2).ToString ());
+                       }
+               }
+
                [Test]
                public void HtmlEncode_LtGt ()
                {
@@ -73,15 +157,15 @@ namespace MonoTests.System.Web {
                public void HtmlEncode_XSS ()
                {
                        string problem = "\xff1cscript\xff1e";  // unicode looks alike <script>
-                       byte[] utf8data = Encoding.UTF8.GetBytes (problem);
+                       byte [] utf8data = Encoding.UTF8.GetBytes (problem);
                        Encoding win1251 = Encoding.GetEncoding ("windows-1251");
-                       byte[] windata = Encoding.Convert (Encoding.UTF8, win1251, utf8data);
+                       byte [] windata = Encoding.Convert (Encoding.UTF8, win1251, utf8data);
                        // now it's a real problem
                        Assert.AreEqual ("<script>", Encoding.ASCII.GetString (windata), "<script>");
 
                        string encoded = HttpUtility.HtmlEncode (problem);
                        Assert.AreEqual ("&#65308;script&#65310;", encoded, "&#65308;script&#65310;");
-                       
+
                        utf8data = Encoding.UTF8.GetBytes (encoded);
                        windata = Encoding.Convert (Encoding.UTF8, win1251, utf8data);
                        Assert.AreEqual ("&#65308;script&#65310;", Encoding.ASCII.GetString (windata), "ok");
@@ -132,61 +216,102 @@ namespace MonoTests.System.Web {
                        for (int i = 0; i < len; i++) {
                                c = s [i];
                                if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
-                                       sb.AppendFormat ("\\u{0:x4}", (int)c);
-                               else switch ((int)c) {
-                                       case 8:
-                                               sb.Append ("\\b");
-                                               break;
-
-                                       case 9:
-                                               sb.Append ("\\t");
-                                               break;
-
-                                       case 10:
-                                               sb.Append ("\\n");
-                                               break;
+                                       sb.AppendFormat ("\\u{0:x4}", (int) c);
+                               else switch ((int) c) {
+                                               case 8:
+                                                       sb.Append ("\\b");
+                                                       break;
+
+                                               case 9:
+                                                       sb.Append ("\\t");
+                                                       break;
+
+                                               case 10:
+                                                       sb.Append ("\\n");
+                                                       break;
+
+                                               case 12:
+                                                       sb.Append ("\\f");
+                                                       break;
+
+                                               case 13:
+                                                       sb.Append ("\\r");
+                                                       break;
+
+                                               case 34:
+                                                       sb.Append ("\\\"");
+                                                       break;
+
+                                               case 92:
+                                                       sb.Append ("\\\\");
+                                                       break;
+
+                                               default:
+                                                       sb.Append (c);
+                                                       break;
+                                       }
+                       }
 
-                                       case 12:
-                                               sb.Append ("\\f");
-                                               break;
+                       if (addDoubleQuotes)
+                               sb.Append ('"');
 
-                                       case 13:
-                                               sb.Append ("\\r");
-                                               break;
+                       return sb.ToString ();
+               }
+#endif
+               [Test]
+               public void HtmlEncode_2 ()
+               {
+                       StringWriter sw;
+#if NET_4_0
+                       AssertExtensions.Throws<ArgumentNullException> (() => {
+                               HttpUtility.HtmlEncode ("string", null);
+                       }, "#A1");
+#else
+                       AssertExtensions.Throws<NullReferenceException> (() => {
+                               HttpUtility.HtmlEncode ("string", null);
+                       }, "#A1");
+#endif
 
-                                       case 34:
-                                               sb.Append ("\\\"");
-                                               break;
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlEncode (null, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A2");
 
-                                       case 92:
-                                               sb.Append ("\\\\");
-                                               break;
+                       sw = new StringWriter ();
+                       HttpUtility.HtmlEncode (String.Empty, sw);
+                       Assert.AreEqual (String.Empty, sw.ToString (), "#A3");
 
-                                       default:
-                                               sb.Append (c);
-                                               break;
-                               }
+                       for (int i = 0; i < encoding_pairs.Length; i += 2) {
+                               sw = new StringWriter ();
+                               HttpUtility.HtmlEncode (encoding_pairs [i], sw);
+                               Assert.AreEqual (encoding_pairs [i + 1], sw.ToString (), "#B" + (i / 2).ToString ());
                        }
+               }
 
-                       if (addDoubleQuotes)
-                               sb.Append ('"');
+               [Test]
+               public void HtmlEncode_3 ()
+               {
+                       Assert.AreEqual (null, HttpUtility.HtmlEncode (null), "#A1");
+                       Assert.AreEqual (String.Empty, HttpUtility.HtmlEncode (String.Empty), "#A2");
 
-                       return sb.ToString ();
+                       for (int i = 0; i < encoding_pairs.Length; i += 2)
+                               Assert.AreEqual (encoding_pairs [i + 1], HttpUtility.HtmlEncode (encoding_pairs [i]), "#B" + (i / 2).ToString ());
                }
-#endif
+
                [Test]
 #if !TARGET_JVM
                [Category ("NotWorking")]
 #endif
-               public void HtmlEncode () {
+               public void HtmlEncode ()
+               {
                        for (char c = char.MinValue; c < char.MaxValue; c++) {
                                String exp = HtmlEncode (c.ToString ());
                                String act = HttpUtility.HtmlEncode (c.ToString ());
                                Assert.AreEqual (exp, act, "HtmlEncode " + c.ToString () + " [" + (int) c + "]");
                        }
                }
-               
-               string HtmlEncode (string s) {
+
+               string HtmlEncode (string s)
+               {
                        if (s == null)
                                return null;
 
@@ -195,9 +320,9 @@ namespace MonoTests.System.Web {
                                char c = s [i];
                                if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159
 #if NET_4_0
                                      || c == '\''
+ || c == '\''
 #endif
-                                       ) {
+) {
                                        needEncode = true;
                                        break;
                                }
@@ -211,36 +336,35 @@ namespace MonoTests.System.Web {
                        int len = s.Length;
                        for (int i = 0; i < len; i++)
                                switch (s [i]) {
-                               case '&':
-                                       output.Append ("&amp;");
-                                       break;
-                               case '>':
-                                       output.Append ("&gt;");
-                                       break;
-                               case '<':
-                                       output.Append ("&lt;");
-                                       break;
-                               case '"':
-                                       output.Append ("&quot;");
-                                       break;
+                                       case '&':
+                                               output.Append ("&amp;");
+                                               break;
+                                       case '>':
+                                               output.Append ("&gt;");
+                                               break;
+                                       case '<':
+                                               output.Append ("&lt;");
+                                               break;
+                                       case '"':
+                                               output.Append ("&quot;");
+                                               break;
 #if NET_4_0
-                               case '\'':
-                                       output.Append ("&#39;");
-                                       break;
+                                       case '\'':
+                                               output.Append ("&#39;");
+                                               break;
 #endif
-                               default:
-                                       // MS starts encoding with &# from 160 and stops at 255.
-                                       // We don't do that. One reason is the 65308/65310 unicode
-                                       // characters that look like '<' and '>'.
-                                       if (s [i] > 159 && s [i] < 256) {
-                                               output.Append ("&#");
-                                               output.Append (((int) s [i]).ToString ());
-                                               output.Append (";");
-                                       }
-                                       else {
-                                               output.Append (s [i]);
-                                       }
-                                       break;
+                                       default:
+                                               // MS starts encoding with &# from 160 and stops at 255.
+                                               // We don't do that. One reason is the 65308/65310 unicode
+                                               // characters that look like '<' and '>'.
+                                               if (s [i] > 159 && s [i] < 256) {
+                                                       output.Append ("&#");
+                                                       output.Append (((int) s [i]).ToString ());
+                                                       output.Append (";");
+                                               } else {
+                                                       output.Append (s [i]);
+                                               }
+                                               break;
                                }
                        return output.ToString ();
                }
@@ -248,7 +372,7 @@ namespace MonoTests.System.Web {
                [Test]
                public void UrlDecodeToBytes ()
                {
-                       byte[] bytes = HttpUtility.UrlDecodeToBytes ("%5c");
+                       byte [] bytes = HttpUtility.UrlDecodeToBytes ("%5c");
                        Assert.AreEqual (1, bytes.Length, "#1");
                        Assert.AreEqual (0x5c, bytes [0], "#2");
                        bytes = HttpUtility.UrlDecodeToBytes ("%5");
@@ -260,36 +384,36 @@ namespace MonoTests.System.Web {
                [Test]
                public void UrlDecode1 ()
                {
-                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=bar", 
-                               HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r"),                              
+                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
+                               HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r"),
                                "UrlDecode1 #1");
-                       
-                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar", 
-                               HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r"),
+
+                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
+                               HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r"),
                                "UrlDecode1 #2");
-                       
-                       Assert.AreEqual ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar", 
-                               HttpUtility.UrlDecode("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r"),
+
+                       Assert.AreEqual ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
+                               HttpUtility.UrlDecode ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r"),
                                "UrlDecode1 #3");
 
-                       Assert.AreEqual ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r", 
-                               HttpUtility.UrlDecode("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r"),
+                       Assert.AreEqual ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
+                               HttpUtility.UrlDecode ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r"),
                                "UrlDecode1 #4");
 
-                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r", 
-                               HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r"),
+                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
+                               HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r"),
                                "UrlDecode1 #5");
 
-                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=bar", 
-                               HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r"),
+                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
+                               HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r"),
                                "UrlDecode1 #6");
-                       
-                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar", 
-                               HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r"),
+
+                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
+                               HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r"),
                                "UrlDecode1 #7");
-                       
-                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r", 
-                               HttpUtility.UrlDecode("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r"),
+
+                       Assert.AreEqual ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
+                               HttpUtility.UrlDecode ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r"),
                                "UrlDecode1 #8");
                }
 
@@ -297,59 +421,59 @@ namespace MonoTests.System.Web {
                public void UrlDecode2 ()
                {
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=bar", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
                                HttpUtility.UrlDecode (
-                               Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r"),
-                               Encoding.UTF8), 
+                               Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r"),
+                               Encoding.UTF8),
                                "UrlDecode2 #1");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
                                HttpUtility.UrlDecode (
-                               Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r"),
-                               Encoding.UTF8), 
+                               Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r"),
+                               Encoding.UTF8),
                                "UrlDecode2 #2");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar", 
+                               "http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
                                HttpUtility.UrlDecode (
-                               Encoding.UTF8.GetBytes("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r"),
-                               Encoding.UTF8), 
+                               Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r"),
+                               Encoding.UTF8),
                                "UrlDecode2 #3");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r", 
+                               "http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
                                HttpUtility.UrlDecode (
-                               Encoding.UTF8.GetBytes("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r"),
-                               Encoding.UTF8), 
+                               Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r"),
+                               Encoding.UTF8),
                                "UrlDecode2 #4");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
                                HttpUtility.UrlDecode (
-                               Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r"),
-                               Encoding.UTF8), 
+                               Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r"),
+                               Encoding.UTF8),
                                "UrlDecode2 #5");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=bar", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
                                HttpUtility.UrlDecode (
-                               Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r"),
-                               Encoding.UTF8), 
+                               Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r"),
+                               Encoding.UTF8),
                                "UrlDecode2 #6");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
                                HttpUtility.UrlDecode (
-                               Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r"),
-                               Encoding.UTF8), 
+                               Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r"),
+                               Encoding.UTF8),
                                "UrlDecode2 #7");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
                                HttpUtility.UrlDecode (
-                               Encoding.UTF8.GetBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r"),
-                               Encoding.UTF8), 
+                               Encoding.UTF8.GetBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r"),
+                               Encoding.UTF8),
                                "UrlDecode2 #8");
                }
 
@@ -357,65 +481,65 @@ namespace MonoTests.System.Web {
                public void UrlDecodeToBytes2 ()
                {
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=bar", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=bar",
                                Encoding.UTF8.GetString (
-                               HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r")),
+                               HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61r")),
                                "UrlDecodeToBytes2 #1");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar",
                                Encoding.UTF8.GetString (
-                               HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r")),
+                               HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%61r")),
                                "UrlDecodeToBytes2 #2");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar", 
+                               "http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%ar",
                                Encoding.UTF8.GetString (
-                               HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r")),
+                               HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/app%Dir/page.aspx?foo=b%%61r")),
                                "UrlDecodeToBytes2 #3");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r", 
+                               "http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r",
                                Encoding.UTF8.GetString (
-                               HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r")),
+                               HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/app%%Dir/page.aspx?foo=b%%r")),
                                "UrlDecodeToBytes2 #4");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=ba%r",
                                Encoding.UTF8.GetString (
-                               HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r")),
+                               HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%61%r")),
                                "UrlDecodeToBytes2 #5");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r",
                                Encoding.UTF8.GetString (
-                               HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r")),
+                               HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r")),
                                "UrlDecodeToBytes2 #6");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r",
                                Encoding.UTF8.GetString (
-                               HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r")),
+                               HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r")),
                                "UrlDecodeToBytes2 #7");
 
                        Assert.AreEqual (
-                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r", 
+                               "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r",
                                Encoding.UTF8.GetString (
-                               HttpUtility.UrlDecodeToBytes("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r")),
+                               HttpUtility.UrlDecodeToBytes ("http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r")),
                                "UrlDecodeToBytes2 #8");
                }
-               
+
                [Test]
                public void EscapedCharacters ()
                {
                        for (int i = 0; i < 256; i++) {
                                string str = new string ((char) i, 1);
                                string encoded = HttpUtility.HtmlEncode (str);
-                               if ((i > 159 && i < 256 ) || i == '&' || i == '<' || i == '>' || i == '"'
+                               if ((i > 159 && i < 256) || i == '&' || i == '<' || i == '>' || i == '"'
 #if NET_4_0
                                       || i == '\''
+ || i == '\''
 #endif
-                                       ) {
+) {
                                        if (encoded [0] != '&' || encoded [encoded.Length - 1] != ';')
                                                Assert.Fail ("Failed for i = " + i);
                                } else if (encoded.Length != 1) {
@@ -424,32 +548,32 @@ namespace MonoTests.System.Web {
                        }
                }
 
-               [Test (Description="Bug #507666")]
+               [Test (Description = "Bug #507666")]
                public void UrlDecode_Bug507666 ()
                {
                        // Get Encoding object.
                        var enc_utf8 = Encoding.UTF8;
-                       var enc_sjis = Encoding.GetEncoding(932);
+                       var enc_sjis = Encoding.GetEncoding (932);
 
                        // Generate equiv. client request query string with url-encoded shift_jis string.
                        var utf8_string = "紅茶"; // it's UTF-8 string
-                       var utf8_bin = enc_utf8.GetBytes(utf8_string); // convert to UTF-8 byte[]
-                       var sjis_bin = Encoding.Convert(enc_utf8, enc_sjis, utf8_bin); // convert to Shift_jis byte[]
-                       var urlenc_string = HttpUtility.UrlEncode(sjis_bin); // equiv. client request query string.
+                       var utf8_bin = enc_utf8.GetBytes (utf8_string); // convert to UTF-8 byte[]
+                       var sjis_bin = Encoding.Convert (enc_utf8, enc_sjis, utf8_bin); // convert to Shift_jis byte[]
+                       var urlenc_string = HttpUtility.UrlEncode (sjis_bin); // equiv. client request query string.
 
                        // Test using UrlDecode only.
-                       var decoded_by_web = HttpUtility.UrlDecode(urlenc_string, enc_sjis);
+                       var decoded_by_web = HttpUtility.UrlDecode (urlenc_string, enc_sjis);
 
                        Assert.AreEqual (utf8_string, decoded_by_web, "#A1");
                }
-               
+
                [Test]
                public void Decode1 ()
                {
                        Assert.AreEqual ("\xE9", HttpUtility.HtmlDecode ("&#233;"));
                }
 
-               [Test (Description="Bug #585992")]
+               [Test (Description = "Bug #585992")]
                public void Decode2 ()
                {
                        string encodedSource = "&#169; == &#xA9; == &#XA9; and &#915; == &#x393; == &#X393;";
@@ -457,13 +581,13 @@ namespace MonoTests.System.Web {
 
                        Assert.AreEqual (utf8Result, HttpUtility.HtmlDecode (encodedSource), "#A1");
                }
-               
+
                [Test]
                public void RoundTrip ()
                {
                        string x = "<html>& hello+= world!";
-                        string y = HttpUtility.HtmlEncode (x);
-                        string z = HttpUtility.HtmlDecode (y);
+                       string y = HttpUtility.HtmlEncode (x);
+                       string z = HttpUtility.HtmlDecode (y);
                        Assert.AreEqual (x, z);
                }
 
@@ -505,7 +629,8 @@ namespace MonoTests.System.Web {
                const string notEncoded = "!'()*-._";
 #endif
 
-               static void UrlPathEncodeChar (char c, Stream result) {
+               static void UrlPathEncodeChar (char c, Stream result)
+               {
 #if NET_2_0
                        if (c < 33 || c > 126) {
 #else
@@ -519,17 +644,16 @@ namespace MonoTests.System.Web {
                                        idx = ((int) bIn [i]) & 0x0F;
                                        result.WriteByte ((byte) hexChars [idx]);
                                }
-                       }
-                       else if (c == ' ') {
+                       } else if (c == ' ') {
                                result.WriteByte ((byte) '%');
                                result.WriteByte ((byte) '2');
                                result.WriteByte ((byte) '0');
-                       }
-                       else
+                       } else
                                result.WriteByte ((byte) c);
                }
 
-               static void UrlEncodeChar (char c, Stream result, bool isUnicode) {
+               static void UrlEncodeChar (char c, Stream result, bool isUnicode)
+               {
                        if (c > 255) {
                                //FIXME: what happens when there is an internal error?
                                //if (!isUnicode)
@@ -537,74 +661,76 @@ namespace MonoTests.System.Web {
                                int idx;
                                int i = (int) c;
 
-                               result.WriteByte ((byte)'%');
-                               result.WriteByte ((byte)'u');
+                               result.WriteByte ((byte) '%');
+                               result.WriteByte ((byte) 'u');
                                idx = i >> 12;
-                               result.WriteByte ((byte)hexChars [idx]);
+                               result.WriteByte ((byte) hexChars [idx]);
                                idx = (i >> 8) & 0x0F;
-                               result.WriteByte ((byte)hexChars [idx]);
+                               result.WriteByte ((byte) hexChars [idx]);
                                idx = (i >> 4) & 0x0F;
-                               result.WriteByte ((byte)hexChars [idx]);
+                               result.WriteByte ((byte) hexChars [idx]);
                                idx = i & 0x0F;
-                               result.WriteByte ((byte)hexChars [idx]);
+                               result.WriteByte ((byte) hexChars [idx]);
                                return;
                        }
-                       
-                       if (c>' ' && notEncoded.IndexOf (c)!=-1) {
-                               result.WriteByte ((byte)c);
+
+                       if (c > ' ' && notEncoded.IndexOf (c) != -1) {
+                               result.WriteByte ((byte) c);
                                return;
                        }
-                       if (c==' ') {
-                               result.WriteByte ((byte)'+');
+                       if (c == ' ') {
+                               result.WriteByte ((byte) '+');
                                return;
                        }
-                       if (    (c < '0') ||
+                       if ((c < '0') ||
                                (c < 'A' && c > '9') ||
                                (c > 'Z' && c < 'a') ||
                                (c > 'z')) {
                                if (isUnicode && c > 127) {
-                                       result.WriteByte ((byte)'%');
-                                       result.WriteByte ((byte)'u');
-                                       result.WriteByte ((byte)'0');
-                                       result.WriteByte ((byte)'0');
-                               }
-                               else
-                                       result.WriteByte ((byte)'%');
-                               
+                                       result.WriteByte ((byte) '%');
+                                       result.WriteByte ((byte) 'u');
+                                       result.WriteByte ((byte) '0');
+                                       result.WriteByte ((byte) '0');
+                               } else
+                                       result.WriteByte ((byte) '%');
+
                                int idx = ((int) c) >> 4;
-                               result.WriteByte ((byte)hexChars [idx]);
+                               result.WriteByte ((byte) hexChars [idx]);
                                idx = ((int) c) & 0x0F;
-                               result.WriteByte ((byte)hexChars [idx]);
-                       }
-                       else
-                               result.WriteByte ((byte)c);
+                               result.WriteByte ((byte) hexChars [idx]);
+                       } else
+                               result.WriteByte ((byte) c);
                }
 
                [Test]
                public void UrlEncode ()
                {
-                       for (char c=char.MinValue; c<char.MaxValue; c++) {
+                       for (char c = char.MinValue; c < char.MaxValue; c++) {
                                byte [] bIn;
                                bIn = Encoding.UTF8.GetBytes (c.ToString ());
                                MemoryStream expected = new MemoryStream ();
                                MemoryStream expUnicode = new MemoryStream ();
 
                                //build expected result for UrlEncode
-                               for (int i = 0; i<bIn.Length; i++)
-                                       UrlEncodeChar ((char)bIn[i], expected, false);
+                               for (int i = 0; i < bIn.Length; i++)
+                                       UrlEncodeChar ((char) bIn [i], expected, false);
                                //build expected result for UrlEncodeUnicode
                                UrlEncodeChar (c, expUnicode, true);
 
-                               Assert.AreEqual (Encoding.ASCII.GetString(expected.ToArray()), HttpUtility.UrlEncode (c.ToString()),
-                                       "UrlEncode "+c.ToString());
-                               Assert.AreEqual (Encoding.ASCII.GetString(expUnicode.ToArray()), HttpUtility.UrlEncodeUnicode (c.ToString()),
-                                       "UrlEncodeUnicode "+c.ToString());
+                               Assert.AreEqual (Encoding.ASCII.GetString (expected.ToArray ()), HttpUtility.UrlEncode (c.ToString ()),
+                                       "UrlEncode " + c.ToString ());
+                               Assert.AreEqual (Encoding.ASCII.GetString (expUnicode.ToArray ()), HttpUtility.UrlEncodeUnicode (c.ToString ()),
+                                       "UrlEncodeUnicode " + c.ToString ());
                        }
                }
 
 #if NET_1_1
                [Test]
-               public void UrlPathEncode () {
+               public void UrlPathEncode ()
+               {
+                       Assert.AreEqual (null, HttpUtility.UrlPathEncode (null), "#A1-1");
+                       Assert.AreEqual (String.Empty, HttpUtility.UrlPathEncode (String.Empty), "#A1-2");
+
                        for (char c = char.MinValue; c < char.MaxValue; c++) {
                                MemoryStream expected = new MemoryStream ();
                                UrlPathEncodeChar (c, expected);
@@ -614,16 +740,16 @@ namespace MonoTests.System.Web {
                                Assert.AreEqual (exp, act, "UrlPathEncode " + c.ToString ());
                        }
                }
-        [Test]
-        public void UrlPathEncode2()
-        {
-            string s = "default.xxx?sdsd=sds";
-            string s2 = HttpUtility.UrlPathEncode(s);
-            Assert.AreEqual(s, s2, "UrlPathEncode " + s);
-        }
+               [Test]
+               public void UrlPathEncode2 ()
+               {
+                       string s = "default.xxx?sdsd=sds";
+                       string s2 = HttpUtility.UrlPathEncode (s);
+                       Assert.AreEqual (s, s2, "UrlPathEncode " + s);
+               }
 
 #endif
-               
+
 #if NET_2_0
                [Test]
 #if TARGET_JVM
@@ -632,37 +758,37 @@ namespace MonoTests.System.Web {
                public void ParseQueryString ()
                {
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value"), "#1",
-                               new string[]{"name"}, new string[][]{new string[]{"value"}});
+                               new string [] { "name" }, new string [] [] { new string [] { "value" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value&foo=bar"), "#2",
-                               new string[]{"name", "foo"}, new string[][]{new string[]{"value"}, new string[]{"bar"}});
+                               new string [] { "name", "foo" }, new string [] [] { new string [] { "value" }, new string [] { "bar" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value&name=bar"), "#3",
-                               new string[]{"name"}, new string[][]{new string[]{"value", "bar"}});
+                               new string [] { "name" }, new string [] [] { new string [] { "value", "bar" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("value"), "#4",
-                               new string[] {null}, new string[][]{new string[]{"value"}});
+                               new string [] { null }, new string [] [] { new string [] { "value" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value&bar"), "#5",
-                               new string[]{"name", null}, new string[][]{new string[]{"value"}, new string[]{"bar"}});
+                               new string [] { "name", null }, new string [] [] { new string [] { "value" }, new string [] { "bar" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("bar&name=value"), "#6",
-                               new string[]{null, "name"}, new string[][]{new string[]{"bar"}, new string[]{"value"}});
+                               new string [] { null, "name" }, new string [] [] { new string [] { "bar" }, new string [] { "value" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("value&bar"), "#7",
-                               new string[]{null}, new string[][]{new string[]{"value", "bar"}});
+                               new string [] { null }, new string [] [] { new string [] { "value", "bar" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString (""), "#8",
-                               new string[0], new string[0][]);
+                               new string [0], new string [0] []);
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("="), "#9",
-                               new string[]{""}, new string[][]{new string[]{""}});
+                               new string [] { "" }, new string [] [] { new string [] { "" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("&"), "#10",
-                               new string[]{null}, new string[][]{new string[]{"", ""}});
+                               new string [] { null }, new string [] [] { new string [] { "", "" } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("?value"), "#11",
-                               new string[]{null}, new string[][]{new string[]{"value"}});
+                               new string [] { null }, new string [] [] { new string [] { "value" } });
 
                        try {
                                HttpUtility.ParseQueryString (null);
@@ -676,26 +802,71 @@ namespace MonoTests.System.Web {
                                Assert.AreEqual (typeof (ArgumentNullException), e.GetType (), "#13");
                        }
 
-                       string str = new string (new char[] {'\u304a', '\u75b2', '\u308c', '\u69d8', '\u3067', '\u3059'});
+                       string str = new string (new char [] { '\u304a', '\u75b2', '\u308c', '\u69d8', '\u3067', '\u3059' });
                        string utf8url = HttpUtility.UrlEncode (str, Encoding.UTF8);
                        ParseQueryString_Helper (HttpUtility.ParseQueryString (utf8url + "=" + utf8url), "#14",
-                               new string[]{str}, new string[][]{new string[] {str}});
+                               new string [] { str }, new string [] [] { new string [] { str } });
 
                        ParseQueryString_Helper (HttpUtility.ParseQueryString ("name=value=test"), "#15",
-                               new string[]{"name"}, new string[][]{new string[]{"value=test"}});
+                               new string [] { "name" }, new string [] [] { new string [] { "value=test" } });
                }
-               static void ParseQueryString_Helper (NameValueCollection nvc, string msg, string[] keys, string[][] values)
+               static void ParseQueryString_Helper (NameValueCollection nvc, string msg, string [] keys, string [] [] values)
                {
                        Assert.AreEqual (keys.Length, nvc.Count, msg + "[Count]");
-                       for (int i = 0; i < keys.Length; i ++) {
-                               Assert.AreEqual (keys[i], nvc.GetKey (i), msg + "[Key]");
-                               string[] tmp = nvc.GetValues (i);
-                               Assert.AreEqual (values[i].Length, tmp.Length, msg + "[ValueCount]");
-                               for (int q = 0; q < values[i].Length; q++)
-                                       Assert.AreEqual (values[i][q], tmp[q], msg + "[Value]");
+                       for (int i = 0; i < keys.Length; i++) {
+                               Assert.AreEqual (keys [i], nvc.GetKey (i), msg + "[Key]");
+                               string [] tmp = nvc.GetValues (i);
+                               Assert.AreEqual (values [i].Length, tmp.Length, msg + "[ValueCount]");
+                               for (int q = 0; q < values [i].Length; q++)
+                                       Assert.AreEqual (values [i] [q], tmp [q], msg + "[Value]");
                        }
                }
 #endif
+               string [] decoding_pairs = {
+       @"&aacute;&Aacute;&acirc;&Acirc;&acute;&aelig;&AElig;&agrave;&Agrave;&alefsym;&alpha;&Alpha;&amp;&and;&ang;&aring;&Aring;&asymp;&atilde;&Atilde;&auml;&Auml;&bdquo;&beta;&Beta;&brvbar;&bull;&cap;&ccedil;&Ccedil;&cedil;&cent;&chi;&Chi;&circ;&clubs;&cong;&copy;&crarr;&cup;&curren;&dagger;&Dagger;&darr;&dArr;&deg;&delta;&Delta;&diams;&divide;&eacute;&Eacute;&ecirc;&Ecirc;&egrave;&Egrave;&empty;&emsp;&ensp;&epsilon;&Epsilon;&equiv;&eta;&Eta;&eth;&ETH;&euml;&Euml;&euro;&exist;&fnof;&forall;&frac12;&frac14;&frac34;&frasl;&gamma;&Gamma;&ge;&gt;&harr;&hArr;&hearts;&hellip;&iacute;&Iacute;&icirc;&Icirc;&iexcl;&igrave;&Igrave;&image;&infin;&int;&iota;&Iota;&iquest;&isin;&iuml;&Iuml;&kappa;&Kappa;&lambda;&Lambda;&lang;&laquo;&larr;&lArr;&lceil;&ldquo;&le;&lfloor;&lowast;&loz;&lrm;&lsaquo;&lsquo;&lt;&macr;&mdash;&micro;&middot;&minus;&mu;&Mu;&nabla;&nbsp;&ndash;&ne;&ni;&not;&notin;&nsub;&ntilde;&Ntilde;&nu;&Nu;&oacute;&Oacute;&ocirc;&Ocirc;&oelig;&OElig;&ograve;&Ograve;&oline;&omega;&Omega;&omicron;&Omicron;&oplus;&or;&ordf;&ordm;&oslash;&Oslash;&otilde;&Otilde;&otimes;&ouml;&Ouml;&para;&part;&permil;&perp;&phi;&Phi;&pi;&Pi;&piv;&plusmn;&pound;&prime;&Prime;&prod;&prop;&psi;&Psi;&quot;&radic;&rang;&raquo;&rarr;&rArr;&rceil;&rdquo;&real;&reg;&rfloor;&rho;&Rho;&rlm;&rsaquo;&rsquo;&sbquo;&scaron;&Scaron;&sdot;&sect;&shy;&sigma;&Sigma;&sigmaf;&sim;&spades;&sub;&sube;&sum;&sup;&sup1;&sup2;&sup3;&supe;&szlig;&tau;&Tau;&there4;&theta;&Theta;&thetasym;&thinsp;&thorn;&THORN;&tilde;&times;&trade;&uacute;&Uacute;&uarr;&uArr;&ucirc;&Ucirc;&ugrave;&Ugrave;&uml;&upsih;&upsilon;&Upsilon;&uuml;&Uuml;&weierp;&xi;&Xi;&yacute;&Yacute;&yen;&yuml;&Yuml;&zeta;&Zeta;&zwj;&zwnj;",
+       @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅  εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‎‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ""√〉»→⇒⌉”ℜ®⌋ρΡ‏›’‚šŠ⋅§­σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ‍‌",
+       @"&aacute;?dCO+6Mk'2R&Aacute;T148quH^^=972 &acirc;#&Acirc;js""{1LZz)U&acute;u@Rv-05n L&aelig;3x}&AElig;!&agrave;,=*-J*&Agrave;=P|B&alefsym;Y<g?cg>jB)&alpha;&Alpha;9#4V`)|&J/n&amp;JVK56X\2q*F&and;Js&ang;6k6&aring;""&Aring;?rGt&asymp;\F <9IM{s-&atilde;(ShK&Atilde;w/[%,ksf93'k&auml;+b$@Q{5&Auml;Uo&bdquo;aN~'ycb>VKGcjo&beta;oR8""%B`L&Beta;I7g""k5]A>^B&brvbar;lllUPg5#b&bull;8Pw,bwSiY ""5]a&cap;_R@m&D+Lz""dKLT&ccedil;KH&I}6)_Q&Ccedil;mS%BZV/*Xo&cedil;s5[&cent;-$|)|L&5~&chi;Y/3cdUrn&Chi;8&circ;&)@KU@scEW2I&clubs;p2,US7f>&m!F&cong;Fr9A%,Ci'y[]F+&copy;PY&crarr;FeCrQI<:pPP~;>&cup;&curren;y J#R&%%i&dagger;Ow,&Dagger;T&darr;KpY`WSAo$i:r&dArr;']=&deg;k12&UI@_&delta;(9xD&Delta;dz&diams;RJdB""F^Y}g&divide;2kbZ2>@yBfu&eacute;9!9J(v&Eacute;\TwTS2X5i&ecirc;SLWaTMQE]e&&Ecirc;jW{\#JAh{Ua=&egrave;5&Egrave;6/GY&empty;U&emsp;n:&ensp;dcSf&epsilon;&Epsilon;1Yoi?X&equiv;.-s!n|i9U?3:6&eta;+|6&Eta;ha?>fm!v,&eth;c;Ky]88&ETH;4T@qO#.&euml;@Kl3%&Euml;X-VvUoE& &euro;o9T:r8\||^ha;&exist;1;/BMT*xJ(a>B&fnof;bH'-TH!6NrP&forall;n&frac12;5Fqvq_e9_""XJ&frac14;vmLXTtu:TVZ,&frac34;syl;qEe:b$5j&frasl;b Hg%T&gamma;[&Gamma;H&ge;&gt;{1wT&harr;o6i~jjKC02&hArr;Q4i6m(2tpl&hearts;&#6iQj!&hellip;4le""4} Lv5{Cs&iacute;D*u]j&Iacute;s}#br=&icirc;fh&Icirc;&iexcl;_B:|&igrave;k2U7lZ;_sI\c]&Igrave;s&image; T!5h"".um9ctz&infin; YDL&int;b(S^&iota;bCm&Iota;_L(\-F&iquest;m9g.h$^HSv&isin;cWH#>&iuml;m0&Iuml;KtgRE3c5@0&&kappa;T[2?\>T^H**&Kappa;=^6 [&lambda;um&Lambda;[3wQ5gT?H(Bo\/&lang;6car8P@AjF4e|b&laquo;397jxG:m&larr;U~?~""f&lArr;`O9iwJ#&lceil;L:q-* !V&ldquo;os)Wq6S{t&le;=80A&lfloor;#tS6&lowast;x`g6a>]U-b&loz;SHb/-]&lrm;m9dm""/d<;xR)4&lsaquo;jrb/,q&lsquo;RW}n2shoM11D|&lt;{}*]WPE#d#&macr;&mdash;yhT   k&micro;&middot;`f~o&minus;{Kmf&mu;d7fmt&Mu;PT@OOrzj&nabla;y ;M01XyI:&nbsp;+l<&ndash;x5|a>62y&ne;GNKJQjmj3&ni;Az&not;?V&notin;,<&nsub;R]Lc&ntilde;kV:&Ntilde;9LLf&Z%`d-H^L&nu;v_yXht&Nu;R1yuF!&oacute;j3]zOwQf_YtT9t&Oacute;}s]&1T&ocirc;&Ocirc;2lEN&oelig;:Rp^X+tPNL.&OElig;x0 ?c3ZP&ograve;3&Ograve;&oline;@nE&omega;uK-*HjL-h5z&Omega;~x&omicron;FNQ8D#{&Omicron;Yj|]'LX&oplus;ie-Y&or;&ordf;$*.c&ordm;VM7KQ.b]hmV &oslash;x{R>J-D_0v&Oslash;Hp&otilde;L'IG&Otilde;`&otimes;E &ouml;>KNCm&Ouml;O2dH_&jd^ >2&para;U%""_n&part;U>F&permil;?TSz0~~&perp;!p@G~bH^E&phi;dg)A&Phi; J<<j_,7Q)dEs,&pi;Z&Pi;_B<@%.&?70&piv;9Y^C|VRPrb4}&plusmn;Yn=9=SQ;`}(e%&pound;y;6|RN;|w&prime;AH=XXf&Prime;&prod;DGf6ol&prop;&psi;]UXZU\vzW4&Psi;e`NY[vrvs&quot;xay&radic;[@\scKIznodD<s&rang;PB C)<itm+&raquo;{t-L&rarr;s^^x<:&sh3&rArr;p^s6Y~3Csw=&rceil;_pKnhDNTmA*p&rdquo;]yG6;,ZuPx&real;xsd&reg;`hXlUn~(pK=N:^&rfloor;OS""P{%j-Wjbx.w&rho;ts^&Rho;r$h<:u^&rlm;Vj}\?7SIauBh&rsaquo;u[ !rto/[UHog&rsquo;xe6gY<24BY.&sbquo;`ZNR}&scaron;uY{Gg;F&Scaron;&sdot;az4TlWKYbJ.h&sect;c`9FrP&shy;5_)&sigma;wx.nP}z@&Sigma;NP9-$@j5&sigmaf;&sim;'ogIt:.@Gul&spades;""p\\rH[)&sub;Om/|3G+BQe&sube;5s!f/O9SA\RJkv&sum;GOFMAXu&sup;W&sup1;&sup2;L`r""}u/n&sup3;.ouLC&supe;(f&szlig;{&tau;B%e [&Tau;$DD>kIdV#X`?^\&there4;|S?W&theta;x)2P.![^5&Theta;zqF""pj&thetasym;#BE1u?&thinsp;GGG>(EQE&thorn;!""y1r/&THORN;m&@[\mw[kNR&tilde;|1G#i[(&times;X<UotTID uY&trade;sWW+TbxY&uacute;kQXr!H6&Uacute;~0TiH1POP&uarr;(CRZttz\EY<&uArr;&bN7ki|&ucirc;r,3j!e$kJE&Z$z&Ucirc;5{0[bvD""[<P)&ugrave;;1EeRSrz/gY/&Ugrave;/1 S`I*q8:Z-&uml;%N)W&upsih;O[2P9 ?&upsilon;O&Upsilon;t&uuml;&Uuml;VLq&weierp;2""(Z'~~""uiX&xi;NCq&Xi;9)S]^v 3&yacute;x""|2&$`G&Yacute;<&Nr&yen;[3NB5f&yuml; c""MzMw3(;""s&Yuml;&zeta;{!&Zeta;oevp1'j(E`vJ&zwj;Si&zwnj;gw>yc*U",
+       @"á?dCO+6Mk'2RÁT148quH^^=972 â#Âjs""{1LZz)U´u@Rv-05n Læ3x}Æ!à,=*-J*À=P|BℵY<g?cg>jB)αΑ9#4V`)|&J/n&JVK56X\2q*F∧Js∠6k6å""Å?rGt≈\F <9IM{s-ã(ShKÃw/[%,ksf93'kä+b$@Q{5ÄUo„aN~'ycb>VKGcjoβoR8""%B`LΒI7g""k5]A>^B¦lllUPg5#b•8Pw,bwSiY ""5]a∩_R@m&D+Lz""dKLTçKH&I}6)_QÇmS%BZV/*Xo¸s5[¢-$|)|L&5~χY/3cdUrnΧ8ˆ&)@KU@scEW2I♣p2,US7f>&m!F≅Fr9A%,Ci'y[]F+©PY↵FeCrQI<:pPP~;>∪¤y J#R&%%i†Ow,‡T↓KpY`WSAo$i:r⇓']=°k12&UI@_δ(9xDΔdz♦RJdB""F^Y}g÷2kbZ2>@yBfué9!9J(vÉ\TwTS2X5iêSLWaTMQE]e&ÊjW{\#JAh{Ua=è5È6/GY∅U n: dcSfεΕ1Yoi?X≡.-s!n|i9U?3:6η+|6Ηha?>fm!v,ðc;Ky]88Ð4T@qO#.ë@Kl3%ËX-VvUoE& €o9T:r8\||^ha;∃1;/BMT*xJ(a>BƒbH'-TH!6NrP∀n½5Fqvq_e9_""XJ¼vmLXTtu:TVZ,¾syl;qEe:b$5j⁄b Hg%Tγ[ΓH≥>{1wT↔o6i~jjKC02⇔Q4i6m(2tpl♥&#6iQj!…4le""4} Lv5{CsíD*u]jÍs}#br=îfhΡ_B:|ìk2U7lZ;_sI\c]Ìsℑ T!5h"".um9ctz∞ YDL∫b(S^ιbCmΙ_L(\-F¿m9g.h$^HSv∈cWH#>ïm0ÏKtgRE3c5@0&κT[2?\>T^H**Κ=^6 [λumΛ[3wQ5gT?H(Bo\/〈6car8P@AjF4e|b«397jxG:m←U~?~""f⇐`O9iwJ#⌈L:q-* !V“os)Wq6S{t≤=80A⌊#tS6∗x`g6a>]U-b◊SHb/-]‎m9dm""/d<;xR)4‹jrb/,q‘RW}n2shoM11D|<{}*]WPE#d#¯—yhT   kµ·`f~o−{Kmfμd7fmtΜPT@OOrzj∇y ;M01XyI: +l<–x5|a>62y≠GNKJQjmj3∋Az¬?V∉,<⊄R]LcñkV:Ñ9LLf&Z%`d-H^Lνv_yXhtΝR1yuF!ój3]zOwQf_YtT9tÓ}s]&1TôÔ2lENœ:Rp^X+tPNL.Œx0 ?c3ZPò3Ò‾@nEωuK-*HjL-h5zΩ~xοFNQ8D#{ΟYj|]'LX⊕ie-Y∨ª$*.cºVM7KQ.b]hmV øx{R>J-D_0vØHpõL'IGÕ`⊗E ö>KNCmÖO2dH_&jd^ >2¶U%""_n∂U>F‰?TSz0~~⊥!p@G~bH^Eφdg)AΦ J<<j_,7Q)dEs,πZΠ_B<@%.&?70ϖ9Y^C|VRPrb4}±Yn=9=SQ;`}(e%£y;6|RN;|w′AH=XXf″∏DGf6ol∝ψ]UXZU\vzW4Ψe`NY[vrvs""xay√[@\scKIznodD<s〉PB C)<itm+»{t-L→s^^x<:&sh3⇒p^s6Y~3Csw=⌉_pKnhDNTmA*p”]yG6;,ZuPxℜxsd®`hXlUn~(pK=N:^⌋OS""P{%j-Wjbx.wρts^Ρr$h<:u^‏Vj}\?7SIauBh›u[ !rto/[UHog’xe6gY<24BY.‚`ZNR}šuY{Gg;FŠ⋅az4TlWKYbJ.h§c`9FrP­5_)σwx.nP}z@ΣNP9-$@j5ς∼'ogIt:.@Gul♠""p\\rH[)⊂Om/|3G+BQe⊆5s!f/O9SA\RJkv∑GOFMAXu⊃W¹²L`r""}u/n³.ouLC⊇(fß{τB%e [Τ$DD>kIdV#X`?^\∴|S?Wθx)2P.![^5ΘzqF""pjϑ#BE1u? GGG>(EQEþ!""y1r/Þm&@[\mw[kNR˜|1G#i[(×X<UotTID uY™sWW+TbxYúkQXr!H6Ú~0TiH1POP↑(CRZttz\EY<⇑&bN7ki|ûr,3j!e$kJE&Z$zÛ5{0[bvD""[<P)ù;1EeRSrz/gY/Ù/1 S`I*q8:Z-¨%N)WϒO[2P9 ?υOΥtüÜVLq℘2""(Z'~~""uiXξNCqΞ9)S]^v 3ýx""|2&$`GÝ<&Nr¥[3NB5fÿ c""MzMw3(;""sŸζ{!Ζoevp1'j(E`vJ‍Si‌gw>yc*U",
+       @"&aacute&Aacute&acirc&Acirc&acute&aelig&AElig&agrave&Agrave&alefsym&alpha&Alpha&amp&and&ang&aring&Aring&asymp&atilde&Atilde&auml&Auml&bdquo&beta&Beta&brvbar&bull&cap&ccedil&Ccedil&cedil&cent&chi&Chi&circ&clubs&cong&copy&crarr&cup&curren&dagger&Dagger&darr&dArr&deg&delta&Delta&diams&divide&eacute&Eacute&ecirc&Ecirc&egrave&Egrave&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&Eta&eth&ETH&euml&Euml&euro&exist&fnof&forall&frac12&frac14&frac34&frasl&gamma&Gamma&ge&gt&harr&hArr&hearts&hellip&iacute&Iacute&icirc&Icirc&iexcl&igrave&Igrave&image&infin&int&iota&Iota&iquest&isin&iuml&Iuml&kappa&Kappa&lambda&Lambda&lang&laquo&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo&lt&macr&mdash&micro&middot&minus&mu&Mu&nabla&nbsp&ndash&ne&ni&not&notin&nsub&ntilde&Ntilde&nu&Nu&oacute&Oacute&ocirc&Ocirc&oelig&OElig&ograve&Ograve&oline&omega&Omega&omicron&Omicron&oplus&or&ordf&ordm&oslash&Oslash&otilde&Otilde&otimes&ouml&Ouml&para&part&permil&perp&phi&Phi&pi&Pi&piv&plusmn&pound&prime&Prime&prod&prop&psi&Psi&quot&radic&rang&raquo&rarr&rArr&rceil&rdquo&real&reg&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot&sect&shy&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup&sup1&sup2&sup3&supe&szlig&tau&Tau&there4&theta&Theta&thetasym&thinsp&thorn&THORN&tilde&times&trade&uacute&Uacute&uarr&uArr&ucirc&Ucirc&ugrave&Ugrave&uml&upsih&upsilon&Upsilon&uuml&Uuml&weierp&xi&Xi&yacute&Yacute&yen&yuml&Yuml&zeta&Zeta&zwj&zwnj",
+       @"&aacute&Aacute&acirc&Acirc&acute&aelig&AElig&agrave&Agrave&alefsym&alpha&Alpha&amp&and&ang&aring&Aring&asymp&atilde&Atilde&auml&Auml&bdquo&beta&Beta&brvbar&bull&cap&ccedil&Ccedil&cedil&cent&chi&Chi&circ&clubs&cong&copy&crarr&cup&curren&dagger&Dagger&darr&dArr&deg&delta&Delta&diams&divide&eacute&Eacute&ecirc&Ecirc&egrave&Egrave&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&Eta&eth&ETH&euml&Euml&euro&exist&fnof&forall&frac12&frac14&frac34&frasl&gamma&Gamma&ge&gt&harr&hArr&hearts&hellip&iacute&Iacute&icirc&Icirc&iexcl&igrave&Igrave&image&infin&int&iota&Iota&iquest&isin&iuml&Iuml&kappa&Kappa&lambda&Lambda&lang&laquo&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo&lt&macr&mdash&micro&middot&minus&mu&Mu&nabla&nbsp&ndash&ne&ni&not&notin&nsub&ntilde&Ntilde&nu&Nu&oacute&Oacute&ocirc&Ocirc&oelig&OElig&ograve&Ograve&oline&omega&Omega&omicron&Omicron&oplus&or&ordf&ordm&oslash&Oslash&otilde&Otilde&otimes&ouml&Ouml&para&part&permil&perp&phi&Phi&pi&Pi&piv&plusmn&pound&prime&Prime&prod&prop&psi&Psi&quot&radic&rang&raquo&rarr&rArr&rceil&rdquo&real&reg&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot&sect&shy&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup&sup1&sup2&sup3&supe&szlig&tau&Tau&there4&theta&Theta&thetasym&thinsp&thorn&THORN&tilde&times&trade&uacute&Uacute&uarr&uArr&ucirc&Ucirc&ugrave&Ugrave&uml&upsih&upsilon&Upsilon&uuml&Uuml&weierp&xi&Xi&yacute&Yacute&yen&yuml&Yuml&zeta&Zeta&zwj&zwnj",
+       @"&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;&#176;&#177;&#178;&#179;&#180;&#181;&#182;&#183;&#184;&#185;&#186;&#187;&#188;&#189;&#190;&#191;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#215;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#247;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;",
+       @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
+       @"&#000;&#001;&#002;&#003;&#004;&#005;&#006;&#007;&#008;&#009;&#010;&#011;&#012;&#013;&#014;&#015;&#016;&#017;&#018;&#019;&#020;&#021;&#022;&#023;&#024;&#025;&#026;&#027;&#028;&#029;&#030;&#031;&#032;",
+#if NET_4_0
+       "&#000;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+#else
+       "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+#endif
+       @"&#x00;&#x01;&#x02;&#x03;&#x04;&#x05;&#x06;&#x07;&#x08;&#x09;&#x0A;&#x0B;&#x0C;&#x0D;&#x0E;&#x0F;&#x10;&#x11;&#x12;&#x13;&#x14;&#x15;&#x16;&#x17;&#x18;&#x19;&#x1A;&#x1B;&#x1C;&#x1D;&#x1E;&#x1F;&#x20;",
+#if NET_4_0    
+       "&#x00;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+#else
+       "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+#endif
+@"&#xA0;&#xA1;&#xA2;&#xA3;&#xA4;&#xA5;&#xA6;&#xA7;&#xA8;&#xA9;&#xAA;&#xAB;&#xAC;&#xAD;&#xAE;&#xAF;&#xB0;&#xB1;&#xB2;&#xB3;&#xB4;&#xB5;&#xB6;&#xB7;&#xB8;&#xB9;&#xBA;&#xBB;&#xBC;&#xBD;&#xBE;&#xBF;&#xC0;&#xC1;&#xC2;&#xC3;&#xC4;&#xC5;&#xC6;&#xC7;&#xC8;&#xC9;&#xCA;&#xCB;&#xCC;&#xCD;&#xCE;&#xCF;&#xD0;&#xD1;&#xD2;&#xD3;&#xD4;&#xD5;&#xD6;&#xD7;&#xD8;&#xD9;&#xDA;&#xDB;&#xDC;&#xDD;&#xDE;&#xDF;&#xE0;&#xE1;&#xE2;&#xE3;&#xE4;&#xE5;&#xE6;&#xE7;&#xE8;&#xE9;&#xEA;&#xEB;&#xEC;&#xED;&#xEE;&#xEF;&#xF0;&#xF1;&#xF2;&#xF3;&#xF4;&#xF5;&#xF6;&#xF7;&#xF8;&#xF9;&#xFA;&#xFB;&#xFC;&#xFD;&#xFE;&#xFF;",
+       " ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
+};
+               string [] encoding_pairs = {
+       @"áÁâ´æÆàÀℵαΑ&∧∠åÅ≈ãÃäÄ„βΒ¦•∩çǸ¢χΧˆ♣≅©↵∪¤†‡↓⇓°δΔ♦÷éÉêÊèÈ∅  εΕ≡ηΗðÐëË€∃ƒ∀½¼¾⁄γΓ≥>↔⇔♥…íÍîΡìÌℑ∞∫ιΙ¿∈ïÏκΚλΛ〈«←⇐⌈“≤⌊∗◊‎‹‘<¯—µ·−μΜ∇ –≠∋¬∉⊄ñÑνΝóÓôÔœŒòÒ‾ωΩοΟ⊕∨ªºøØõÕ⊗öÖ¶∂‰⊥φΦπΠϖ±£′″∏∝ψΨ""√〉»→⇒⌉”ℜ®⌋ρΡ‏›’‚šŠ⋅§­σΣς∼♠⊂⊆∑⊃¹²³⊇ßτΤ∴θΘϑ þޘיúÚ↑⇑ûÛùÙ¨ϒυΥüÜ℘ξΞýÝ¥ÿŸζΖ‍‌",
+       @"&#225;&#193;&#226;&#194;&#180;&#230;&#198;&#224;&#192;ℵαΑ&amp;∧∠&#229;&#197;≈&#227;&#195;&#228;&#196;„βΒ&#166;•∩&#231;&#199;&#184;&#162;χΧˆ♣≅&#169;↵∪&#164;†‡↓⇓&#176;δΔ♦&#247;&#233;&#201;&#234;&#202;&#232;&#200;∅  εΕ≡ηΗ&#240;&#208;&#235;&#203;€∃ƒ∀&#189;&#188;&#190;⁄γΓ≥&gt;↔⇔♥…&#237;&#205;&#238;&#206;&#161;&#236;&#204;ℑ∞∫ιΙ&#191;∈&#239;&#207;κΚλΛ〈&#171;←⇐⌈“≤⌊∗◊‎‹‘&lt;&#175;—&#181;&#183;−μΜ∇&#160;–≠∋&#172;∉⊄&#241;&#209;νΝ&#243;&#211;&#244;&#212;œŒ&#242;&#210;‾ωΩοΟ⊕∨&#170;&#186;&#248;&#216;&#245;&#213;⊗&#246;&#214;&#182;∂‰⊥φΦπΠϖ&#177;&#163;′″∏∝ψΨ&quot;√〉&#187;→⇒⌉”ℜ&#174;⌋ρΡ‏›’‚šŠ⋅&#167;&#173;σΣς∼♠⊂⊆∑⊃&#185;&#178;&#179;⊇&#223;τΤ∴θΘϑ &#254;&#222;˜&#215;™&#250;&#218;↑⇑&#251;&#219;&#249;&#217;&#168;ϒυΥ&#252;&#220;℘ξΞ&#253;&#221;&#165;&#255;ŸζΖ‍‌",
+       @"á9cP!qdO#hU@mg1ÁK%0<}*âÂ5[Y;lfMQ$4`´uim7E`%_1zVDkæ[cM{Æt9y:E8Hb;;$;Y'àUa6wÀ<$@W9$4NL*h#'ℵk\zαG}{}hC-Α|=QhyLT%`&wB!@#x51R 4C∧]Z3n∠y>:{JZ'v|c0;N""åzcWM'z""gÅo-JX!r.e≈Z+BT{wF8+ãQ 6P1o?x""ef}vUÃ+</Nt)TI]sä0Eg_'mn&6WY[8Äay+ u[3kqoZ„i6rβUX\:_y1A^x.p>+Β`uf3/HI¦7bCRv%o$X3:•∩ç|(fgiA|MBLf=y@Ǹ¢R,qDW;F9<mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(©7DZ`1>r~.↵4B&R∪+x2T`q[M-lq'¤~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr>74~yHB=&EI⇓,u@Jx°δcC`2,Δo2B]6PP8♦|{!wZa&,*N'$6÷-{nVSgO]%(Ié6Éêosx-2xDI!Ê_]7Ub%èYG4`Gx{ÈH>vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6TðT!Z:Nq_0797;!Ð4]QNë9+>x9>nm-s8YËwZ}vY€:HHf∃;=0,?ƒIr`I:i5'∀z_$Q<½_sCF;=$43DpDz]¼.aMTIEwx\ogn7A¾CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV>↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Okíjt$NKbGrÍ""+alp<îRÎ%¡yìz2 AÌ-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ¿6qqb0|BQ$H%p+d∈.Wa=YBfS'd-EOïISG+=W;GHÏ3||b-icT""qAκ*/ΚλN>j}""WrqΛt]dm-Xe/v〈\«$F< X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8[""3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO‎&-L>DsUej‹C[n]Q<%UoyO‘?zUgpr+62sY<T{7n*^¯4CH]6^e/x/—uT->mQh\""µZSTN!F(U%5·17:Cu<−)*c2μTΜ%:6-e&L[ Xos/4∇]Xr 1c=qyv4HSw~HL~–{+qG?/}≠6`S"",+pL∋>¬B9∉G;6P]xc 0Bs⊄7,j0Sj2/&ñFsÑ=νKs*?[54bV1ΝQ%p6P0.Lrc`yóA/*`6sBH?67Ó&ôÔI""Hœ~e9Œ>oò5eZI}iy?}KÒS‾anD1nXωIΩu""ο:Mz$(""joU^[mΟ7M1f$j>N|Q/@(⊕de6(∨WXb<~;tI?bt#ªU:º+wb(*cA=øjb c%*?Uj6<T02Ø/A}j'MõjlfYlR~er7D@3WÕe:XTLF?|""yd7x⊗eV6Mmw2{K<lö%B%/o~r9Öc1Q TJnd^¶;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv±TAvFo+;JE,2?£""'6F9fRp′,0″<∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e>S~kO""'4""/i4\>!]H;T^0o√8_G`*8&An\rhc)〉&UEk»-(YtC→(zerUTMTe,'@{⇒mlzVhU<S,5}9DM⌉/%R=10*[{'=:”C0ℜ4HoT?-#+l[SnPs®0 bV⌋TρΡjb1}OJ:,0z6‏oTxP""""FOT[;›'’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&u§= _CqlY1O'­qNf|&σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D¹KVO²%:~Iq?IUcHr4y³QP@R't!⊇vßYnI@FXxT<τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR  %`g|*8DECþ_[Þ'8,?˜}gnaz_U×-F^™9ZDO86ú]y\ecHQSÚk-07/AT|0Ce↑F⇑*}e|r$6ln!V`ûA!*8H,mÛ~6G6w&GùsPL6ÙQ¨}J^NO}=._Mnϒ{&υ=ΥWD+f>fy|nNyP*Jüo8,lh\ÜN`'g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=Sý9tI_Ý}p(D51=X¥cH8L)$*]~=IÿdbŸf>J^1Dnζ@(drH;91?{6`xJΖ4N4[u+5‍9.W\v‌]GGtKvCC0`A",
+#if NET_4_0    
+       @"&#225;9cP!qdO#hU@mg1&#193;K%0&lt;}*&#226;&#194;5[Y;lfMQ$4`&#180;uim7E`%_1zVDk&#230;[cM{&#198;t9y:E8Hb;;$;Y&#39;&#224;Ua6w&#192;&lt;$@W9$4NL*h#&#39;ℵk\zαG}{}hC-Α|=QhyLT%`&amp;wB!@#x51R 4C∧]Z3n∠y&gt;:{JZ&#39;v|c0;N&quot;&#229;zcWM&#39;z&quot;g&#197;o-JX!r.e≈Z+BT{wF8+&#227;Q 6P1o?x&quot;ef}vU&#195;+&lt;/Nt)TI]s&#228;0Eg_&#39;mn&amp;6WY[8&#196;ay+ u[3kqoZ„i6rβUX\:_y1A^x.p&gt;+Β`uf3/HI&#166;7bCRv%o$X3:•∩&#231;|(fgiA|MBLf=y@&#199;&#184;&#162;R,qDW;F9&lt;mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(&#169;7DZ`1&gt;r~.↵4B&amp;R∪+x2T`q[M-lq&#39;&#164;~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr&gt;74~yHB=&amp;EI⇓,u@Jx&#176;δcC`2,Δo2B]6PP8♦|{!wZa&amp;,*N&#39;$6&#247;-{nVSgO]%(I&#233;6&#201;&#234;osx-2xDI!&#202;_]7Ub%&#232;YG4`Gx{&#200;H&gt;vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6T&#240;T!Z:Nq_0797;!&#208;4]QN&#235;9+&gt;x9&gt;nm-s8Y&#203;wZ}vY€:HHf∃;=0,?ƒIr`I:i5&#39;∀z_$Q&lt;&#189;_sCF;=$43DpDz]&#188;.aMTIEwx\ogn7A&#190;CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV&gt;↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Ok&#237;jt$NKbGr&#205;&quot;+alp&lt;&#238;R&#206;%&#161;y&#236;z2 A&#204;-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ&#191;6qqb0|BQ$H%p+d∈.Wa=YBfS&#39;d-EO&#239;ISG+=W;GH&#207;3||b-icT&quot;qAκ*/ΚλN&gt;j}&quot;WrqΛt]dm-Xe/v〈\&#171;$F&lt; X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8[&quot;3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO‎&amp;-L&gt;DsUej‹C[n]Q&lt;%UoyO‘?zUgpr+62sY&lt;T{7n*^&#175;4CH]6^e/x/—uT-&gt;mQh\&quot;&#181;ZSTN!F(U%5&#183;17:Cu&lt;−)*c2μTΜ%:6-e&amp;L[ Xos/4∇]Xr&#160;1c=qyv4HSw~HL~–{+qG?/}≠6`S&quot;,+pL∋&gt;&#172;B9∉G;6P]xc 0Bs⊄7,j0Sj2/&amp;&#241;Fs&#209;=νKs*?[54bV1ΝQ%p6P0.Lrc`y&#243;A/*`6sBH?67&#211;&amp;&#244;&#212;I&quot;Hœ~e9Œ&gt;o&#242;5eZI}iy?}K&#210;S‾anD1nXωIΩu&quot;ο:Mz$(&quot;joU^[mΟ7M1f$j&gt;N|Q/@(⊕de6(∨WXb&lt;~;tI?bt#&#170;U:&#186;+wb(*cA=&#248;jb c%*?Uj6&lt;T02&#216;/A}j&#39;M&#245;jlfYlR~er7D@3W&#213;e:XTLF?|&quot;yd7x⊗eV6Mmw2{K&lt;l&#246;%B%/o~r9&#214;c1Q TJnd^&#182;;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv&#177;TAvFo+;JE,2?&#163;&quot;&#39;6F9fRp′,0″&lt;∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e&gt;S~kO&quot;&#39;4&quot;/i4\&gt;!]H;T^0o√8_G`*8&amp;An\rhc)〉&amp;UEk&#187;-(YtC→(zerUTMTe,&#39;@{⇒mlzVhU&lt;S,5}9DM⌉/%R=10*[{&#39;=:”C0ℜ4HoT?-#+l[SnPs&#174;0 bV⌋TρΡjb1}OJ:,0z6‏oTxP&quot;&quot;FOT[;›&#39;’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&amp;u&#167;= _CqlY1O&#39;&#173;qNf|&amp;σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D&#185;KVO&#178;%:~Iq?IUcHr4y&#179;QP@R&#39;t!⊇v&#223;YnI@FXxT&lt;τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR  %`g|*8DEC&#254;_[&#222;&#39;8,?˜}gnaz_U&#215;-F^™9ZDO86&#250;]y\ecHQS&#218;k-07/AT|0Ce↑F⇑*}e|r$6ln!V`&#251;A!*8H,m&#219;~6G6w&amp;G&#249;sPL6&#217;Q&#168;}J^NO}=._Mnϒ{&amp;υ=ΥWD+f&gt;fy|nNyP*J&#252;o8,lh\&#220;N`&#39;g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=S&#253;9tI_&#221;}p(D51=X&#165;cH8L)$*]~=I&#255;dbŸf&gt;J^1Dnζ@(drH;91?{6`xJΖ4N4[u+5‍9.W\v‌]GGtKvCC0`A",
+#else
+       @"&#225;9cP!qdO#hU@mg1&#193;K%0&lt;}*&#226;&#194;5[Y;lfMQ$4`&#180;uim7E`%_1zVDk&#230;[cM{&#198;t9y:E8Hb;;$;Y'&#224;Ua6w&#192;&lt;$@W9$4NL*h#'ℵk\zαG}{}hC-Α|=QhyLT%`&amp;wB!@#x51R 4C∧]Z3n∠y&gt;:{JZ'v|c0;N&quot;&#229;zcWM'z&quot;g&#197;o-JX!r.e≈Z+BT{wF8+&#227;Q 6P1o?x&quot;ef}vU&#195;+&lt;/Nt)TI]s&#228;0Eg_'mn&amp;6WY[8&#196;ay+ u[3kqoZ„i6rβUX\:_y1A^x.p&gt;+Β`uf3/HI&#166;7bCRv%o$X3:•∩&#231;|(fgiA|MBLf=y@&#199;&#184;&#162;R,qDW;F9&lt;mχU]$)Q`w^KF^(hΧ?ukX+O!UOftˆZE♣@MLR(vcH]k8≅CU;r#(&#169;7DZ`1&gt;r~.↵4B&amp;R∪+x2T`q[M-lq'&#164;~3rp%~-Gd†;35wU+II1tQJ‡`NGh[↓Lr&gt;74~yHB=&amp;EI⇓,u@Jx&#176;δcC`2,Δo2B]6PP8♦|{!wZa&amp;,*N'$6&#247;-{nVSgO]%(I&#233;6&#201;&#234;osx-2xDI!&#202;_]7Ub%&#232;YG4`Gx{&#200;H&gt;vwMPJ∅ :Z-u#ph l,s*8(AεΕOnj|Gy|]iYLPR≡5Wi:(vZUUK.YlηDΗ6T&#240;T!Z:Nq_0797;!&#208;4]QN&#235;9+&gt;x9&gt;nm-s8Y&#203;wZ}vY€:HHf∃;=0,?ƒIr`I:i5'∀z_$Q&lt;&#189;_sCF;=$43DpDz]&#188;.aMTIEwx\ogn7A&#190;CuJD[Hke#⁄E]M%γE:IEk}Γ{qXfzeUS≥kqW yxV&gt;↔AzJ:$fJ⇔3IMDqU\myWjsL♥…Ok&#237;jt$NKbGr&#205;&quot;+alp&lt;&#238;R&#206;%&#161;y&#236;z2 A&#204;-%;jyMK{Umdℑi|}+Za8jyWDS#I∞]NyqN*v:m-∫03Aιf9m.:+z0@OfVoΙ_gfPilLZ&#191;6qqb0|BQ$H%p+d∈.Wa=YBfS'd-EO&#239;ISG+=W;GH&#207;3||b-icT&quot;qAκ*/ΚλN&gt;j}&quot;WrqΛt]dm-Xe/v〈\&#171;$F&lt; X←]=8H8⇐c⌈|“JgZ)+(7,}≤s8[&quot;3%C4JvN⌊H55TAKEZ*%Z)d.∗R9z//!q◊D`643eO‎&amp;-L&gt;DsUej‹C[n]Q&lt;%UoyO‘?zUgpr+62sY&lt;T{7n*^&#175;4CH]6^e/x/—uT-&gt;mQh\&quot;&#181;ZSTN!F(U%5&#183;17:Cu&lt;−)*c2μTΜ%:6-e&amp;L[ Xos/4∇]Xr&#160;1c=qyv4HSw~HL~–{+qG?/}≠6`S&quot;,+pL∋&gt;&#172;B9∉G;6P]xc 0Bs⊄7,j0Sj2/&amp;&#241;Fs&#209;=νKs*?[54bV1ΝQ%p6P0.Lrc`y&#243;A/*`6sBH?67&#211;&amp;&#244;&#212;I&quot;Hœ~e9Œ&gt;o&#242;5eZI}iy?}K&#210;S‾anD1nXωIΩu&quot;ο:Mz$(&quot;joU^[mΟ7M1f$j&gt;N|Q/@(⊕de6(∨WXb&lt;~;tI?bt#&#170;U:&#186;+wb(*cA=&#248;jb c%*?Uj6&lt;T02&#216;/A}j'M&#245;jlfYlR~er7D@3W&#213;e:XTLF?|&quot;yd7x⊗eV6Mmw2{K&lt;l&#246;%B%/o~r9&#214;c1Q TJnd^&#182;;∂|‰_.⊥E_bim;gvA{wqφeΦ^-!Dcπ8LB6k4PΠ(5D |Y3ϖptuh)3Mv&#177;TAvFo+;JE,2?&#163;&quot;'6F9fRp′,0″&lt;∏N∝C%}JC7qY(7))UWψ 7=rmQaΨeD!G5e&gt;S~kO&quot;'4&quot;/i4\&gt;!]H;T^0o√8_G`*8&amp;An\rhc)〉&amp;UEk&#187;-(YtC→(zerUTMTe,'@{⇒mlzVhU&lt;S,5}9DM⌉/%R=10*[{'=:”C0ℜ4HoT?-#+l[SnPs&#174;0 bV⌋TρΡjb1}OJ:,0z6‏oTxP&quot;&quot;FOT[;›'’-:Ll)I0^$p.‚S_šNBr9)K[Š1⋅$-S4/G&amp;u&#167;= _CqlY1O'&#173;qNf|&amp;σGp}ΣP3:8ς∼[ItI♠8⊂BQn~!KO:+~ma⊆FV.u 4wD∑lE+kQ|gZ];Y⊃DK69EEM$D&#185;KVO&#178;%:~Iq?IUcHr4y&#179;QP@R't!⊇v&#223;YnI@FXxT&lt;τvL[4H95mfΤF0JzQsrxNZry∴Bn#t(θ*OΘw=Z%ϑ+*l^3C)5HCNmR  %`g|*8DEC&#254;_[&#222;'8,?˜}gnaz_U&#215;-F^™9ZDO86&#250;]y\ecHQS&#218;k-07/AT|0Ce↑F⇑*}e|r$6ln!V`&#251;A!*8H,m&#219;~6G6w&amp;G&#249;sPL6&#217;Q&#168;}J^NO}=._Mnϒ{&amp;υ=ΥWD+f&gt;fy|nNyP*J&#252;o8,lh\&#220;N`'g℘(sJ8h3P]cF ξcdQ_OC]U#ΞBby=S&#253;9tI_&#221;}p(D51=X&#165;cH8L)$*]~=I&#255;dbŸf&gt;J^1Dnζ@(drH;91?{6`xJΖ4N4[u+5‍9.W\v‌]GGtKvCC0`A",
+#endif
+       @"&aacute&Aacute&acirc&Acirc&acute&aelig&AElig&agrave&Agrave&alefsym&alpha&Alpha&amp&and&ang&aring&Aring&asymp&atilde&Atilde&auml&Auml&bdquo&beta&Beta&brvbar&bull&cap&ccedil&Ccedil&cedil&cent&chi&Chi&circ&clubs&cong&copy&crarr&cup&curren&dagger&Dagger&darr&dArr&deg&delta&Delta&diams&divide&eacute&Eacute&ecirc&Ecirc&egrave&Egrave&empty&emsp&ensp&epsilon&Epsilon&equiv&eta&Eta&eth&ETH&euml&Euml&euro&exist&fnof&forall&frac12&frac14&frac34&frasl&gamma&Gamma&ge&gt&harr&hArr&hearts&hellip&iacute&Iacute&icirc&Icirc&iexcl&igrave&Igrave&image&infin&int&iota&Iota&iquest&isin&iuml&Iuml&kappa&Kappa&lambda&Lambda&lang&laquo&larr&lArr&lceil&ldquo&le&lfloor&lowast&loz&lrm&lsaquo&lsquo&lt&macr&mdash&micro&middot&minus&mu&Mu&nabla&nbsp&ndash&ne&ni&not&notin&nsub&ntilde&Ntilde&nu&Nu&oacute&Oacute&ocirc&Ocirc&oelig&OElig&ograve&Ograve&oline&omega&Omega&omicron&Omicron&oplus&or&ordf&ordm&oslash&Oslash&otilde&Otilde&otimes&ouml&Ouml&para&part&permil&perp&phi&Phi&pi&Pi&piv&plusmn&pound&prime&Prime&prod&prop&psi&Psi&quot&radic&rang&raquo&rarr&rArr&rceil&rdquo&real&reg&rfloor&rho&Rho&rlm&rsaquo&rsquo&sbquo&scaron&Scaron&sdot&sect&shy&sigma&Sigma&sigmaf&sim&spades&sub&sube&sum&sup&sup1&sup2&sup3&supe&szlig&tau&Tau&there4&theta&Theta&thetasym&thinsp&thorn&THORN&tilde&times&trade&uacute&Uacute&uarr&uArr&ucirc&Ucirc&ugrave&Ugrave&uml&upsih&upsilon&Upsilon&uuml&Uuml&weierp&xi&Xi&yacute&Yacute&yen&yuml&Yuml&zeta&Zeta&zwj&zwnj",
+       @"&amp;aacute&amp;Aacute&amp;acirc&amp;Acirc&amp;acute&amp;aelig&amp;AElig&amp;agrave&amp;Agrave&amp;alefsym&amp;alpha&amp;Alpha&amp;amp&amp;and&amp;ang&amp;aring&amp;Aring&amp;asymp&amp;atilde&amp;Atilde&amp;auml&amp;Auml&amp;bdquo&amp;beta&amp;Beta&amp;brvbar&amp;bull&amp;cap&amp;ccedil&amp;Ccedil&amp;cedil&amp;cent&amp;chi&amp;Chi&amp;circ&amp;clubs&amp;cong&amp;copy&amp;crarr&amp;cup&amp;curren&amp;dagger&amp;Dagger&amp;darr&amp;dArr&amp;deg&amp;delta&amp;Delta&amp;diams&amp;divide&amp;eacute&amp;Eacute&amp;ecirc&amp;Ecirc&amp;egrave&amp;Egrave&amp;empty&amp;emsp&amp;ensp&amp;epsilon&amp;Epsilon&amp;equiv&amp;eta&amp;Eta&amp;eth&amp;ETH&amp;euml&amp;Euml&amp;euro&amp;exist&amp;fnof&amp;forall&amp;frac12&amp;frac14&amp;frac34&amp;frasl&amp;gamma&amp;Gamma&amp;ge&amp;gt&amp;harr&amp;hArr&amp;hearts&amp;hellip&amp;iacute&amp;Iacute&amp;icirc&amp;Icirc&amp;iexcl&amp;igrave&amp;Igrave&amp;image&amp;infin&amp;int&amp;iota&amp;Iota&amp;iquest&amp;isin&amp;iuml&amp;Iuml&amp;kappa&amp;Kappa&amp;lambda&amp;Lambda&amp;lang&amp;laquo&amp;larr&amp;lArr&amp;lceil&amp;ldquo&amp;le&amp;lfloor&amp;lowast&amp;loz&amp;lrm&amp;lsaquo&amp;lsquo&amp;lt&amp;macr&amp;mdash&amp;micro&amp;middot&amp;minus&amp;mu&amp;Mu&amp;nabla&amp;nbsp&amp;ndash&amp;ne&amp;ni&amp;not&amp;notin&amp;nsub&amp;ntilde&amp;Ntilde&amp;nu&amp;Nu&amp;oacute&amp;Oacute&amp;ocirc&amp;Ocirc&amp;oelig&amp;OElig&amp;ograve&amp;Ograve&amp;oline&amp;omega&amp;Omega&amp;omicron&amp;Omicron&amp;oplus&amp;or&amp;ordf&amp;ordm&amp;oslash&amp;Oslash&amp;otilde&amp;Otilde&amp;otimes&amp;ouml&amp;Ouml&amp;para&amp;part&amp;permil&amp;perp&amp;phi&amp;Phi&amp;pi&amp;Pi&amp;piv&amp;plusmn&amp;pound&amp;prime&amp;Prime&amp;prod&amp;prop&amp;psi&amp;Psi&amp;quot&amp;radic&amp;rang&amp;raquo&amp;rarr&amp;rArr&amp;rceil&amp;rdquo&amp;real&amp;reg&amp;rfloor&amp;rho&amp;Rho&amp;rlm&amp;rsaquo&amp;rsquo&amp;sbquo&amp;scaron&amp;Scaron&amp;sdot&amp;sect&amp;shy&amp;sigma&amp;Sigma&amp;sigmaf&amp;sim&amp;spades&amp;sub&amp;sube&amp;sum&amp;sup&amp;sup1&amp;sup2&amp;sup3&amp;supe&amp;szlig&amp;tau&amp;Tau&amp;there4&amp;theta&amp;Theta&amp;thetasym&amp;thinsp&amp;thorn&amp;THORN&amp;tilde&amp;times&amp;trade&amp;uacute&amp;Uacute&amp;uarr&amp;uArr&amp;ucirc&amp;Ucirc&amp;ugrave&amp;Ugrave&amp;uml&amp;upsih&amp;upsilon&amp;Upsilon&amp;uuml&amp;Uuml&amp;weierp&amp;xi&amp;Xi&amp;yacute&amp;Yacute&amp;yen&amp;yuml&amp;Yuml&amp;zeta&amp;Zeta&amp;zwj&amp;zwnj",
+       @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
+       @"&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;&#176;&#177;&#178;&#179;&#180;&#181;&#182;&#183;&#184;&#185;&#186;&#187;&#188;&#189;&#190;&#191;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#215;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#247;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;",
+       "&#000;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       "&amp;#000;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       "&#x00;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       "&amp;#x00;\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ",
+       @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ",
+       @"&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;&#176;&#177;&#178;&#179;&#180;&#181;&#182;&#183;&#184;&#185;&#186;&#187;&#188;&#189;&#190;&#191;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#215;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#247;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;",
+};
+
        }
 }
 
index 0073d38e18b0a168c1d0efc339185a055fded6f3..0809ee737b6e3904f44c77aef225ee33a7148f44 100644 (file)
@@ -25,8 +25,8 @@ $(APPLICATION_ASSEMBLY): bin/.stamp $(APPLICATION_ASSEMBLY_SOURCES)
        $(CSCOMPILE) $(APPLICATION_ASSEMBLY_MCS_FLAGS) $(APPLICATION_ASSEMBLY_SOURCES) -target:library -out:$(APPLICATION_ASSEMBLY)
 
 bin/.stamp:
-       install -d -m 755 ApplicationPreStartMethods/bin/
-       touch ApplicationPreStartMethods/bin/.stamp
+       install -d -m 755 bin/
+       touch bin/.stamp
 endif
 
 clean: