/// <summary>
        /// Converts a string to a number (used in type coercion).
        /// </summary>
        /// <returns> The result of parsing the string as a number. </returns>
        internal static double CoerceToNumber(string input)
        {
            var reader = new System.IO.StringReader(input);

            // Skip whitespace and line terminators.
            while (IsWhiteSpaceOrLineTerminator(reader.Peek()))
            {
                reader.Read();
            }

            // Empty strings return 0.
            int firstChar = reader.Read();

            if (firstChar == -1)
            {
                return(0.0);
            }

            // The number can start with a plus or minus sign.
            bool negative = false;

            switch (firstChar)
            {
            case '-':
                negative  = true;
                firstChar = reader.Read();
                break;

            case '+':
                firstChar = reader.Read();
                break;
            }

            // Infinity or -Infinity are also valid.
            if (firstChar == 'I')
            {
                var restOfString1 = reader.ReadToEnd();
                if (restOfString1 == null)
                {
                    throw new InvalidOperationException("Reader returned null.");
                }

                if (restOfString1.StartsWith("nfinity", StringComparison.Ordinal))
                {
                    // Check the end of the string for junk.
                    for (int i = 7; i < restOfString1.Length; i++)
                    {
                        if (IsWhiteSpaceOrLineTerminator(restOfString1[i]) == false)
                        {
                            return(double.NaN);
                        }
                    }
                    return(negative ? double.NegativeInfinity : double.PositiveInfinity);
                }
            }

            // Return NaN if the first digit is not a number or a period.
            if ((firstChar < '0' || firstChar > '9') && firstChar != '.')
            {
                return(double.NaN);
            }

            // Parse the number.
            NumberParser.ParseCoreStatus status;
            double result = NumberParser.ParseCore(reader, (char)firstChar, out status, true, false);

            // Handle various error cases.
            switch (status)
            {
            case ParseCoreStatus.NoDigits:
            case ParseCoreStatus.NoExponent:
                return(double.NaN);
            }

            // Check the end of the string for junk.
            var nfinityString = reader.ReadToEnd();

            if (nfinityString == null)
            {
                throw new InvalidOperationException("Reader returned null.");
            }

            if (nfinityString.Any(t => IsWhiteSpaceOrLineTerminator(t) == false))
            {
                return(double.NaN);
            }

            return(negative ? -result : result);
        }
 /// <summary>
 /// Converts any JavaScript value to a primitive number value.
 /// </summary>
 /// <param name="value"> The value to convert. </param>
 /// <returns> A primitive number value. </returns>
 public static double ToNumber(object value)
 {
     if (value is double)
     {
         return((double)value);
     }
     if (value is SByte)
     {
         return((SByte)value);
     }
     if (value is Int16)
     {
         return((Int16)value);
     }
     if (value is Int32)
     {
         return((Int32)value);
     }
     if (value is Int64)
     {
         return((Int64)value);
     }
     if (value is Byte)
     {
         return((Byte)value);
     }
     if (value is UInt16)
     {
         return((UInt16)value);
     }
     if (value is UInt32)
     {
         return((UInt32)value);
     }
     if (value is UInt64)
     {
         return((UInt64)value);
     }
     if (value == null || value == Undefined.Value)
     {
         return(double.NaN);
     }
     if (value == Null.Value)
     {
         return(+0);
     }
     if (value is bool)
     {
         return((bool)value ? 1 : 0);
     }
     if (value is string)
     {
         return(NumberParser.CoerceToNumber((string)value));
     }
     if (value is ConcatenatedString)
     {
         return(NumberParser.CoerceToNumber(value.ToString()));
     }
     if (value is ObjectInstance)
     {
         return(ToNumber(ToPrimitive(value, PrimitiveTypeHint.Number)));
     }
     throw new ArgumentException(string.Format("Cannot convert object of type '{0}' to a number.", value.GetType()), "value");
 }