Support separator characters.

Fixes #49
diff --git a/double-conversion/double-conversion.cc b/double-conversion/double-conversion.cc
index ba83bef..ecd1a5e 100644
--- a/double-conversion/double-conversion.cc
+++ b/double-conversion/double-conversion.cc
@@ -551,6 +551,26 @@
   return radix > 10 && c >= a_character && c < a_character + radix - 10;
 }
 
+// Returns true, when the iterator is equal to end.
+template<class Iterator>
+static bool Advance (Iterator* it, char separator, int base, Iterator& end) {
+  if (separator == StringToDoubleConverter::kNoSeparator) {
+    ++(*it);
+    return *it == end;
+  }
+  if (!isDigit(**it, base)) {
+    ++(*it);
+    return *it == end;
+  }
+  ++(*it);
+  if (*it == end) return true;
+  if (*it + 1 == end) return false;
+  if (**it == separator && isDigit(*(*it + 1), base)) {
+    ++(*it);
+  }
+  return *it == end;
+}
+
 // Checks whether the string in the range start-end is a hex-float string.
 // This function assumes that the leading '0x'/'0X' is already consumed.
 //
@@ -561,27 +581,35 @@
 template<class Iterator>
 static bool IsHexFloatString(Iterator start,
                              Iterator end,
+                             char separator,
                              bool allow_trailing_junk) {
   ASSERT(start != end);
 
   Iterator current = start;
 
-  while (current != end && isDigit(*current, 16)) ++current;
-  if (current == end) return false;
-  if (*current == '.') {
-    ++current;
-    while (current != end && isDigit(*current, 16)) ++current;
-    if (current - start == 1) return false;  // Only the '.', but no digits.
+  bool saw_digit = false;
+  while (isDigit(*current, 16)) {
+    saw_digit = true;
+    if (Advance(&current, separator, 16, end)) return false;
   }
-  if (current == end) return false;
+  if (*current == '.') {
+    if (Advance(&current, separator, 16, end)) return false;
+    while (isDigit(*current, 16)) {
+      saw_digit = true;
+      if (Advance(&current, separator, 16, end)) return false;
+    }
+    if (!saw_digit) return false;  // Only the '.', but no digits.
+  }
   if (*current != 'p' && *current != 'P') return false;
-  ++current;
-  if (current == end) return false;
-  if (*current == '+' || *current == '-') ++current;
-  if (current == end) return false;
+  if (Advance(&current, separator, 16, end)) return false;
+  if (*current == '+' || *current == '-') {
+    if (Advance(&current, separator, 16, end)) return false;
+  }
   if (!isDigit(*current, 10)) return false;
-  ++current;
-  while (current != end && isDigit(*current, 10)) ++current;
+  if (Advance(&current, separator, 16, end)) return true;
+  while (isDigit(*current, 10)) {
+    if (Advance(&current, separator, 16, end)) return true;
+  }
   return allow_trailing_junk || !AdvanceToNonspace(&current, end);
 }
 
@@ -594,6 +622,7 @@
 static double RadixStringToIeee(Iterator* current,
                                 Iterator end,
                                 bool sign,
+                                char separator,
                                 bool parse_as_hex_float,
                                 bool allow_trailing_junk,
                                 double junk_string_value,
@@ -601,7 +630,7 @@
                                 bool* result_is_junk) {
   ASSERT(*current != end);
   ASSERT(!parse_as_hex_float ||
-      IsHexFloatString(*current, end, allow_trailing_junk));
+      IsHexFloatString(*current, end, separator, allow_trailing_junk));
 
   const int kDoubleSize = Double::kSignificandSize;
   const int kSingleSize = Single::kSignificandSize;
@@ -609,15 +638,6 @@
 
   *result_is_junk = true;
 
-  // Skip leading 0s.
-  while (**current == '0') {
-    ++(*current);
-    if (*current == end) {
-      *result_is_junk = false;
-      return SignedZero(sign);
-    }
-  }
-
   int64_t number = 0;
   int exponent = 0;
   const int radix = (1 << radix_log_2);
@@ -625,7 +645,15 @@
   // Only relevant if parse_as_hex_float is true.
   bool post_decimal = false;
 
-  do {
+  // Skip leading 0s.
+  while (**current == '0') {
+    if (Advance(current, separator, radix, end)) {
+      *result_is_junk = false;
+      return SignedZero(sign);
+    }
+  }
+
+  while (true) {
     int digit;
     if (IsDecimalDigitForRadix(**current, radix)) {
       digit = static_cast<char>(**current) - '0';
@@ -638,7 +666,8 @@
       if (post_decimal) exponent -= radix_log_2;
     } else if (parse_as_hex_float && **current == '.') {
       post_decimal = true;
-      ++(*current);
+      Advance(current, separator, radix, end);
+      ASSERT(*current != end);
       continue;
     } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
       break;
@@ -668,14 +697,15 @@
 
       bool zero_tail = true;
       for (;;) {
-        ++(*current);
+        if (Advance(current, separator, radix, end)) break;
         if (parse_as_hex_float && **current == '.') {
           // Just run over the '.'. We are just trying to see whether there is
           // a non-zero digit somewhere.
-          ++(*current);
+          Advance(current, separator, radix, end);
+          ASSERT(*current != end);
           post_decimal = true;
         }
-        if (*current == end || !isDigit(**current, radix)) break;
+        if (!isDigit(**current, radix)) break;
         zero_tail = zero_tail && **current == '0';
         if (!post_decimal) exponent += radix_log_2;
       }
@@ -704,8 +734,8 @@
       }
       break;
     }
-    ++(*current);
-  } while (*current != end);
+    if (Advance(current, separator, radix, end)) break;
+  }
 
   ASSERT(number < ((int64_t)1 << kSignificandSize));
   ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
@@ -714,18 +744,21 @@
 
   if (parse_as_hex_float) {
     ASSERT(**current == 'p' || **current == 'P');
-    ++(*current);
+    Advance(current, separator, radix, end);
+    ASSERT(*current != end);
     bool is_negative = false;
     if (**current == '+') {
-      ++(*current);
+      Advance(current, separator, radix, end);
+      ASSERT(*current != end);
     } else if (**current == '-') {
       is_negative = true;
-      ++(*current);
+      Advance(current, separator, radix, end);
+      ASSERT(*current != end);
     }
     int written_exponent = 0;
-    while (*current != end && IsDecimalDigitForRadix(**current, 10)) {
+    while (IsDecimalDigitForRadix(**current, 10)) {
       written_exponent = 10 * written_exponent + **current - '0';
-      ++(*current);
+      if (Advance(current, separator, radix, end)) break;
     }
     if (is_negative) written_exponent = -written_exponent;
     exponent += written_exponent;
@@ -761,7 +794,6 @@
   const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
   const bool allow_case_insensibility = (flags_ & ALLOW_CASE_INSENSIBILITY) != 0;
 
-
   // To make sure that iterator dereferencing is valid the following
   // convention is used:
   // 1. Each '++current' statement is followed by check for equality to 'end'.
@@ -849,8 +881,7 @@
 
   bool leading_zero = false;
   if (*current == '0') {
-    ++current;
-    if (current == end) {
+    if (Advance(&current, separator_, 10, end)) {
       *processed_characters_count = static_cast<int>(current - input);
       return SignedZero(sign);
     }
@@ -863,7 +894,7 @@
       ++current;
 
       bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
-                          IsHexFloatString(current, end, allow_trailing_junk);
+                IsHexFloatString(current, end, separator_, allow_trailing_junk);
 
       if (current == end) return junk_string_value_;  // "0x"
       if (!parse_as_hex_float && !isDigit(*current, 16)) {
@@ -874,6 +905,7 @@
       double result = RadixStringToIeee<4>(&current,
                                            end,
                                            sign,
+                                           separator_,
                                            parse_as_hex_float,
                                            allow_trailing_junk,
                                            junk_string_value_,
@@ -888,8 +920,7 @@
 
     // Ignore leading zeros in the integer part.
     while (*current == '0') {
-      ++current;
-      if (current == end) {
+      if (Advance(&current, separator_, 10, end)) {
         *processed_characters_count = static_cast<int>(current - input);
         return SignedZero(sign);
       }
@@ -910,8 +941,7 @@
       nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
     }
     octal = octal && *current < '8';
-    ++current;
-    if (current == end) goto parsing_done;
+    if (Advance(&current, separator_, 10, end)) goto parsing_done;
   }
 
   if (significant_digits == 0) {
@@ -922,8 +952,7 @@
     if (octal && !allow_trailing_junk) return junk_string_value_;
     if (octal) goto parsing_done;
 
-    ++current;
-    if (current == end) {
+    if (Advance(&current, separator_, 10, end)) {
       if (significant_digits == 0 && !leading_zero) {
         return junk_string_value_;
       } else {
@@ -936,8 +965,7 @@
       // Integer part consists of 0 or is absent. Significant digits start after
       // leading zeros (if any).
       while (*current == '0') {
-        ++current;
-        if (current == end) {
+        if (Advance(&current, separator_, 10, end)) {
           *processed_characters_count = static_cast<int>(current - input);
           return SignedZero(sign);
         }
@@ -957,8 +985,7 @@
         // Ignore insignificant digits in the fractional part.
         nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
       }
-      ++current;
-      if (current == end) goto parsing_done;
+      if (Advance(&current, separator_, 10, end)) goto parsing_done;
     }
   }
 
@@ -1045,6 +1072,7 @@
     result = RadixStringToIeee<3>(&start,
                                   buffer + buffer_pos,
                                   sign,
+                                  separator_,
                                   false, // Don't parse as hex_float.
                                   allow_trailing_junk,
                                   junk_string_value_,
diff --git a/double-conversion/double-conversion.h b/double-conversion/double-conversion.h
index 86cf25e..7495d17 100644
--- a/double-conversion/double-conversion.h
+++ b/double-conversion/double-conversion.h
@@ -399,6 +399,8 @@
     ALLOW_HEX_FLOATS = 128,
   };
 
+  static const uc16 kNoSeparator = '\0';
+
   // Flags should be a bit-or combination of the possible Flags-enum.
   //  - NO_FLAGS: no special flags.
   //  - ALLOW_HEX: recognizes the prefix "0x". Hex numbers may only be integers.
@@ -459,6 +461,12 @@
   //  - they must not have the same first character.
   //  - they must not start with digits.
   //
+  // If the separator character is not kNoSeparator, then that specific
+  // character is ignored when in between two valid digits of the significant.
+  // It is not allowed to appear in the exponent.
+  // It is not allowed to lead or trail the number.
+  // It is not allowed to appear twice next to each other.
+  //
   // Examples:
   //  flags = ALLOW_HEX | ALLOW_TRAILING_JUNK,
   //  empty_string_value = 0.0,
@@ -498,16 +506,26 @@
   //    StringToDouble("01239E45") -> 1239e45.
   //    StringToDouble("-infinity") -> NaN  // junk_string_value.
   //    StringToDouble("NaN") -> NaN  // junk_string_value.
+  //
+  //  flags = NO_FLAGS,
+  //  separator = ' ':
+  //    StringToDouble("1 2 3 4") -> 1234.0
+  //    StringToDouble("1  2") -> NaN // junk_string_value
+  //    StringToDouble("1 000 000.0") -> 1000000.0
+  //    StringToDouble("1.000 000") -> 1.0
+  //    StringToDouble("1.0e1 000") -> NaN // junk_string_value
   StringToDoubleConverter(int flags,
                           double empty_string_value,
                           double junk_string_value,
                           const char* infinity_symbol,
-                          const char* nan_symbol)
+                          const char* nan_symbol,
+                          uc16 separator = kNoSeparator)
       : flags_(flags),
         empty_string_value_(empty_string_value),
         junk_string_value_(junk_string_value),
         infinity_symbol_(infinity_symbol),
-        nan_symbol_(nan_symbol) {
+        nan_symbol_(nan_symbol),
+        separator_(separator) {
   }
 
   // Performs the conversion.
@@ -542,6 +560,7 @@
   const double junk_string_value_;
   const char* const infinity_symbol_;
   const char* const nan_symbol_;
+  const uc16 separator_;
 
   template <class Iterator>
   double StringToIeee(Iterator start_pointer,
diff --git a/test/cctest/test-conversions.cc b/test/cctest/test-conversions.cc
index cf556e6..1173416 100644
--- a/test/cctest/test-conversions.cc
+++ b/test/cctest/test-conversions.cc
@@ -1720,9 +1720,10 @@
 
 static double StrToD16(const uc16* str16, int length, int flags,
                        double empty_string_value,
-                       int* processed_characters_count, bool* processed_all) {
+                       int* processed_characters_count, bool* processed_all,
+                       uc16 separator = StringToDoubleConverter::kNoSeparator) {
   StringToDoubleConverter converter(flags, empty_string_value, Double::NaN(),
-                                    NULL, NULL);
+                                    NULL, NULL, separator);
   double result =
       converter.StringToDouble(str16, length, processed_characters_count);
   *processed_all = (length == *processed_characters_count);
@@ -1731,9 +1732,10 @@
 
 
 static double StrToD(const char* str, int flags, double empty_string_value,
-                     int* processed_characters_count, bool* processed_all) {
+                     int* processed_characters_count, bool* processed_all,
+                     uc16 separator = StringToDoubleConverter::kNoSeparator) {
   StringToDoubleConverter converter(flags, empty_string_value, Double::NaN(),
-                                    NULL, NULL);
+                                    NULL, NULL, separator);
   double result = converter.StringToDouble(str, strlen(str),
                                            processed_characters_count);
   *processed_all =
@@ -1748,7 +1750,8 @@
   int processed_characters_count16;
   bool processed_all16;
   double result16 = StrToD16(buffer16, len, flags, empty_string_value,
-                             &processed_characters_count16, &processed_all16);
+                             &processed_characters_count16, &processed_all16,
+                             separator);
   CHECK_EQ(result, result16);
   CHECK_EQ(*processed_characters_count, processed_characters_count16);
   return result;
@@ -3196,6 +3199,323 @@
 }
 
 
+TEST(StringToDoubleSeparator) {
+  int flags;
+  int processed;
+  bool all_used;
+  char separator;
+
+  separator = '\'';
+  flags = StringToDoubleConverter::NO_FLAGS;
+
+  CHECK_EQ(1.0, StrToD("000'001.0'0", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(1.0, StrToD("0'0'0'0'0'1.0'0", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(), StrToD("'1.0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1'.0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.'0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0''1.0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e1'0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e1'", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e'1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0'e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("+'1.0e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("-'1.0e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e+'1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e-'1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e'+1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e'-1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  separator = ' ';
+  flags = StringToDoubleConverter::NO_FLAGS;
+
+  CHECK_EQ(1.0, StrToD("000 001.0 0", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(1.0, StrToD("0 0 0 0 0 1.0 0", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(), StrToD(" 1.0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1 .0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1. 0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0  1.0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e1 0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e1 ", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e 1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0 e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("+ 1.0e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("- 1.0e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e+ 1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e- 1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e +1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e -1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  separator = ' ';
+  flags = StringToDoubleConverter::ALLOW_LEADING_SPACES |
+      StringToDoubleConverter::ALLOW_TRAILING_SPACES;
+
+  CHECK_EQ(1.0, StrToD("000 001.0 0", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(1.0, StrToD("0 0 0 0 0 1.0 0", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(1.0, StrToD("  000 001.0 0   ", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(1.0, StrToD("   0 0 0 0 0 1.0 0   ", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(1.0, StrToD(" 1.0", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(), StrToD("1 .0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1. 0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0  1.0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e1 0", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(10.0, StrToD("1.0e1 ", flags, 0.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e 1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0 e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("+ 1.0e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("- 1.0e1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e+ 1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e- 1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e +1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("1.0e -1", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  separator = ' ';
+  flags = StringToDoubleConverter::ALLOW_HEX |
+      StringToDoubleConverter::ALLOW_HEX_FLOATS |
+      StringToDoubleConverter::ALLOW_LEADING_SPACES |
+      StringToDoubleConverter::ALLOW_TRAILING_SPACES;
+
+  CHECK_EQ(18.0, StrToD("0x1 2", flags, 0.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(0.0, StrToD("0x0 0", flags, 1.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(static_cast<double>(0x123456789),
+           StrToD("0x1 2 3 4 5 6 7 8 9", flags, Double::NaN(),
+                  &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(18.0, StrToD(" 0x1 2 ", flags, 0.0,
+                        &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(0.0, StrToD(" 0x0 ", flags, 1.0,
+                       &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(static_cast<double>(0x123456789),
+           StrToD(" 0x1 2 3 4 5 6 7 8 9 ", flags, Double::NaN(),
+                  &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(static_cast<double>(0xabcdef),
+           StrToD("0xa b c d e f", flags, 0.0,
+                  &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(), StrToD("0x 1 2", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD("0 x0", flags, 1.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x1 2  3 4 5 6 7 8 9", flags, Double::NaN(),
+                  &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(), StrToD(" 0 x1 2 ", flags, 0.0,
+                                 &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(3.0,
+           StrToD("0x0 3p0", flags, 0.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(0.0,
+           StrToD("0x.0 0p0", flags, 0.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(3.0,
+           StrToD("0x3.0 0p0", flags, 0.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(3.0,
+           StrToD("0x0 3.p0", flags, 0.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x 3p0", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x.0 p0", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x3.0p0 0", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x0 3.p 0", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x3p+ 0", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x.0p- 0", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x3.0p +0", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("0x0 3.p -0", flags, 0.0, &processed, &all_used));
+  CHECK_EQ(0, processed);
+}
+
 TEST(StringToDoubleSpecialValues) {
   int processed;
   int flags = StringToDoubleConverter::NO_FLAGS;
@@ -3369,6 +3689,28 @@
 
   CHECK_EQ(Double::NaN(), StrToD("NaN", flags, 0.0, &processed, &all_used));
   CHECK_EQ(0, processed);
+
+  flags = StringToDoubleConverter::NO_FLAGS;
+  char separator = ' ';
+  CHECK_EQ(1234.0,
+           StrToD("1 2 3 4", flags, 0.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("1  2", flags, 0.0, &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
+
+  CHECK_EQ(1000000.0,
+           StrToD("1 000 000.0", flags, 0.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(1.0,
+           StrToD("1.000 000", flags, 0.0, &processed, &all_used, separator));
+  CHECK(all_used);
+
+  CHECK_EQ(Double::NaN(),
+           StrToD("1.0e1 000", flags, 0.0, &processed, &all_used, separator));
+  CHECK_EQ(0, processed);
 }