diff --git a/double-conversion.cabal b/double-conversion.cabal
--- a/double-conversion.cabal
+++ b/double-conversion.cabal
@@ -1,5 +1,5 @@
 name:           double-conversion
-version:        0.2.0.6
+version:        2.0.1.0
 license:        BSD3
 license-file:   LICENSE
 homepage:       https://github.com/bos/double-conversion
@@ -8,7 +8,6 @@
 author:         Bryan O'Sullivan <bos@serpentine.com>
 maintainer:     Bryan O'Sullivan <bos@serpentine.com>
 stability:      experimental
-tested-with:    GHC == 7.0.3
 synopsis:       Fast conversion between double precision floating point and text
 cabal-version:  >= 1.8
 build-type:     Simple
@@ -34,16 +33,23 @@
     README.markdown
     benchmarks/*.cabal
     benchmarks/*.hs
+    double-conversion/*.cmake.in
+    double-conversion/AUTHORS
+    double-conversion/CMakeLists.txt
     double-conversion/COPYING
+    double-conversion/Changelog
     double-conversion/LICENSE
     double-conversion/Makefile
     double-conversion/README
     double-conversion/SConstruct
     double-conversion/src/*.cc
     double-conversion/src/*.h
+    double-conversion/src/CMakeLists.txt
     double-conversion/src/SConscript
+    double-conversion/test/CMakeLists.txt
     double-conversion/test/cctest/*.cc
     double-conversion/test/cctest/*.h
+    double-conversion/test/cctest/CMakeLists.txt
     double-conversion/test/cctest/SConscript
     include/*.h
     tests/*.hs
@@ -51,6 +57,7 @@
 flag developer
   description: operate in developer mode
   default: False
+  manual: True
 
 library
   c-sources:
diff --git a/double-conversion/AUTHORS b/double-conversion/AUTHORS
new file mode 100644
--- /dev/null
+++ b/double-conversion/AUTHORS
@@ -0,0 +1,14 @@
+# Below is a list of people and organizations that have contributed
+# to the double-conversion project.  Names should be added to the
+# list like so:
+#
+#   Name/Organization <email address>
+
+Google Inc.
+Mozilla Foundation
+
+Jeff Muizelaar <jmuizelaar@mozilla.com>
+Mike Hommey <mhommey@mozilla.com>
+Martin Olsson <mnemo@minimum.se>
+Kent Williams <chaircrusher@gmail.com>
+Elan Ruusamäe <glen@delfi.ee>
diff --git a/double-conversion/CMakeLists.txt b/double-conversion/CMakeLists.txt
new file mode 100644
--- /dev/null
+++ b/double-conversion/CMakeLists.txt
@@ -0,0 +1,93 @@
+cmake_minimum_required(VERSION 2.8)
+project(double-conversion)
+
+# pick a version #
+set(double-conversion_VERSION 2.0.1)
+set(double-conversion_SOVERSION_MAJOR 1)
+set(double-conversion_SOVERSION_MINOR 0)
+set(double-conversion_SOVERSION_PATCH 0)
+set(double-conversion_SOVERSION
+  ${double-conversion_SOVERSION_MAJOR}.${double-conversion_SOVERSION_MINOR}.${double-conversion_SOVERSION_PATCH})
+
+# set paths for install -- empty initially
+# Offer the user the choice of overriding the installation directories
+set(INSTALL_BIN_DIR CACHE PATH "Installation directory for libraries")
+set(INSTALL_LIB_DIR CACHE PATH "Installation directory for libraries")
+set(INSTALL_INCLUDE_DIR CACHE PATH "Installation directory for include")
+# set suffix for CMake files used for packaging
+if(WIN32 AND NOT CYGWIN)
+  set(INSTALL_CMAKE_DIR CMake)
+else()
+  set(INSTALL_CMAKE_DIR lib/CMake/double-conversion)
+endif()
+
+# Make relative paths absolute (needed later)
+foreach(p LIB BIN INCLUDE CMAKE)
+  set(var INSTALL_${p}_DIR)
+  if(NOT IS_ABSOLUTE "${${var}}")
+    set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
+  endif()
+endforeach()
+
+#
+# set up include dirs
+include_directories("${PROJECT_SOURCE_DIR}/src"
+  "${PROJECT_BINARY_DIR}"
+  )
+
+# Add src subdirectory
+add_subdirectory(src)
+
+#
+# set up testing if requested
+option(BUILD_TESTING "Build test programs" OFF)
+if(BUILD_TESTING)
+  enable_testing()
+  include(CTest)
+  add_subdirectory(test)
+endif()
+
+#
+# mention the library target as export library
+export(TARGETS double-conversion
+  FILE "${PROJECT_BINARY_DIR}/double-conversionLibraryDepends.cmake")
+
+#
+# set this build as an importable package
+export(PACKAGE double-conversion)
+
+#
+# make a cmake file -- in this case, all that needs defining
+# is double-conversion_INCLUDE_DIRS
+configure_file(double-conversionBuildTreeSettings.cmake.in
+  "${PROJECT_BINARY_DIR}/double-conversionBuildTreeSettings.cmake"
+  @ONLY)
+
+#
+# determine where include is relative to the CMake dir in
+# in installed tree
+file(RELATIVE_PATH CONF_REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}"
+  "${INSTALL_INCLUDE_DIR}")
+
+#
+# sets up config to be used by CMake find_package
+configure_file(double-conversionConfig.cmake.in
+  "${PROJECT_BINARY_DIR}/double-conversionConfig.cmake"
+  @ONLY)
+#
+# Export version # checked by find_package
+configure_file(double-conversionConfigVersion.cmake.in
+  "${PROJECT_BINARY_DIR}/double-conversionConfigVersion.cmake"
+  @ONLY)
+#
+# install config files for find_package
+install(FILES
+  "${PROJECT_BINARY_DIR}/double-conversionConfig.cmake"
+  "${PROJECT_BINARY_DIR}/double-conversionConfigVersion.cmake"
+  DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev)
+
+
+#
+# generates install cmake files to find libraries in installation.
+install(EXPORT double-conversionLibraryDepends DESTINATION
+  "${INSTALL_CMAKE_DIR}" COMPONENT dev)
diff --git a/double-conversion/Changelog b/double-conversion/Changelog
new file mode 100644
--- /dev/null
+++ b/double-conversion/Changelog
@@ -0,0 +1,34 @@
+2014-03-08:
+  Update version number for cmake.
+  Support shared libraries with cmake.
+  Add build instructions to the README.
+
+2014-01-12:
+  Tagged v2.0.1.
+  Fix compilation for ARMv8 64bit (used wrong define).
+  Improved SConstruct file. Thanks to Milan Bouchet-Valat and Elan Ruusamäe.
+  Fixed lots of warnings (especially on Windows). Thanks to Greg Smith.
+
+2013-11-09:
+  Tagged v2.0.0.
+  String-to-Double|Float: ALLOW_LEADING_SPACES and similar flags now include
+  new-lines, tabs and all Unicode whitespace characters.
+
+2013-11-09:
+  Tagged v1.1.2.
+  Add support for ARM 64 and OsX ppc.
+  Rewrite tests so they pass under Visual Studio.
+  Add CMake build system support.
+  Fix warnings.
+
+2012-06-10:
+  Tagged v1.1.1.
+  Null terminate exponent buffer (only an issue when asserts are enabled).
+  Support more architectures.
+
+2012-02-05:
+  Merged in Single-branch with single-precision support.
+  Tagged v1.1 (based on b28450f33e1db493948a535d8f84e88fa211bd10).
+
+2012-02-05:
+  Tagged v1.0 (based on eda0196e9ac8fcdf59e92cb62885ee0af5391969).
diff --git a/double-conversion/README b/double-conversion/README
--- a/double-conversion/README
+++ b/double-conversion/README
@@ -9,3 +9,46 @@
 
 There is extensive documentation in src/double-conversion.h. Other examples can
 be found in test/cctest/test-conversions.cc.
+
+
+Building
+========
+
+This library can be built with scons [0] or cmake [1].
+The checked-in Makefile simply forwards to scons, and provides a
+shortcut to run all tests:
+
+    make
+    make test
+
+Scons
+-----
+
+The easiest way to install this library is to use `scons`. It builds
+the static and shared library, and is set up to install those at the
+correct locations:
+
+    scons install
+
+Use the `DESTDIR` option to change the target directory:
+
+    scons DESTDIR=alternative_directory install
+
+Cmake
+-----
+
+To use cmake run `cmake .` in the root directory. This overwrites the
+existing Makefile.
+
+Use `-DBUILD_SHARED_LIBS=ON` to enable the compilation of shared libraries.
+Note that this disables static libraries. There is currently no way to
+build both libraries at the same time with cmake.
+
+Use `-DBUILD_TESTING=ON` to build the test executable.
+
+    cmake . -DBUILD_TESTING=ON
+    make
+    test/cctest/cctest --list | tr -d '<' | xargs test/cctest/cctest
+
+[0]: http://www.scons.org
+[1]: http://www.cmake.org
diff --git a/double-conversion/SConstruct b/double-conversion/SConstruct
--- a/double-conversion/SConstruct
+++ b/double-conversion/SConstruct
@@ -1,14 +1,46 @@
+# vim:ft=python
+import os
+
 double_conversion_sources = ['src/' + x for x in SConscript('src/SConscript')]
 double_conversion_test_sources = ['test/cctest/' + x for x in SConscript('test/cctest/SConscript')]
-test = double_conversion_sources + double_conversion_test_sources
-print(test)
-env = Environment(CPPPATH='#/src', LIBS=['m', 'stdc++'])
+
+DESTDIR = ARGUMENTS.get('DESTDIR', '')
+prefix = ARGUMENTS.get('prefix', '/usr/local')
+lib = ARGUMENTS.get('libsuffix', 'lib')
+libdir = os.path.join(DESTDIR + prefix, lib)
+
+env = Environment(CPPPATH='#/src', LIBS=['m', 'stdc++'],
+    CXXFLAGS=ARGUMENTS.get('CXXFLAGS', ''))
 debug = ARGUMENTS.get('debug', 0)
 optimize = ARGUMENTS.get('optimize', 0)
+env.Replace(CXX = ARGUMENTS.get('CXX', 'g++'))
+
+# for shared lib, requires scons 2.3.0
+env['SHLIBVERSION'] = '1.0.0'
+
+CCFLAGS = []
 if int(debug):
-  env.Append(CCFLAGS = '-g -Wall -Werror')
+  CCFLAGS.append(ARGUMENTS.get('CXXFLAGS', '-g -Wall -Wshadow -Werror'))
 if int(optimize):
-  env.Append(CCFLAGS = '-O3')
-print double_conversion_sources
-print double_conversion_test_sources
-env.Program('run_tests', double_conversion_sources + double_conversion_test_sources)
+  CCFLAGS.append(ARGUMENTS.get('CXXFLAGS', '-O3'))
+
+env.Append(CCFLAGS = " ".join(CCFLAGS))
+
+double_conversion_shared_objects = [
+    env.SharedObject(src) for src in double_conversion_sources]
+double_conversion_static_objects = [
+    env.StaticObject(src) for src in double_conversion_sources]
+
+library_name = 'double-conversion'
+
+static_lib = env.StaticLibrary(library_name, double_conversion_static_objects)
+static_lib_pic = env.StaticLibrary(library_name + '_pic', double_conversion_shared_objects)
+shared_lib = env.SharedLibrary(library_name, double_conversion_shared_objects)
+
+env.Program('run_tests', double_conversion_test_sources, LIBS=[static_lib])
+
+env.InstallVersionedLib(libdir, shared_lib)
+env.Install(libdir, static_lib)
+env.Install(libdir, static_lib_pic)
+
+env.Alias('install', libdir)
diff --git a/double-conversion/double-conversionBuildTreeSettings.cmake.in b/double-conversion/double-conversionBuildTreeSettings.cmake.in
new file mode 100644
--- /dev/null
+++ b/double-conversion/double-conversionBuildTreeSettings.cmake.in
@@ -0,0 +1,2 @@
+set(double-conversion_INCLUDE_DIRS
+  "@PROJECT_SOURCE_DIR@/src")
diff --git a/double-conversion/double-conversionConfig.cmake.in b/double-conversion/double-conversionConfig.cmake.in
new file mode 100644
--- /dev/null
+++ b/double-conversion/double-conversionConfig.cmake.in
@@ -0,0 +1,17 @@
+# - Config file for the double-conversion package
+# It defines the following variables
+# double-conversion_INCLUDE_DIRS
+# double-conversion_LIBRARIES
+
+get_filename_component(double-conversion_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+if(EXISTS "${double-conversion_CMAKE_DIR}/CMakeCache.txt")
+  include("${double-conversion_CMAKE_DIR}/double-conversionBuildTreeSettings.cmake")
+else()
+  set(double-conversion_INCLUDE_DIRS
+    "${double-conversion_CMAKE_DIR}/@CONF_REL_INCLUDE_DIR@/include/double-conversion")
+endif()
+
+include("${double-conversion_CMAKE_DIR}/double-conversionLibraryDepends.cmake")
+
+set(double-conversion_LIBRARIES double-conversion)
diff --git a/double-conversion/double-conversionConfigVersion.cmake.in b/double-conversion/double-conversionConfigVersion.cmake.in
new file mode 100644
--- /dev/null
+++ b/double-conversion/double-conversionConfigVersion.cmake.in
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@double-conversion_VERSION@")
+ 
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+  set(PACKAGE_VERSION_COMPATIBLE TRUE)
+  if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+    set(PACKAGE_VERSION_EXACT TRUE)
+  endif()
+endif()
diff --git a/double-conversion/src/CMakeLists.txt b/double-conversion/src/CMakeLists.txt
new file mode 100644
--- /dev/null
+++ b/double-conversion/src/CMakeLists.txt
@@ -0,0 +1,48 @@
+
+set(headers
+  bignum.h
+  cached-powers.h
+  diy-fp.h
+  double-conversion.h
+  fast-dtoa.h
+  fixed-dtoa.h
+  ieee.h
+  strtod.h
+  utils.h
+  )
+
+add_library(double-conversion
+bignum.cc
+bignum-dtoa.cc
+cached-powers.cc
+diy-fp.cc
+double-conversion.cc
+fast-dtoa.cc
+fixed-dtoa.cc
+strtod.cc
+${headers}
+)
+
+#
+# associates the list of headers with the library
+# for the purposes of installation/import into other projects
+set_target_properties(double-conversion
+    PROPERTIES PUBLIC_HEADER "${headers}")
+
+if (BUILD_SHARED_LIBS)
+  set_target_properties(double-conversion
+    PROPERTIES VERSION ${double-conversion_SOVERSION}
+               SOVERSION ${double-conversion_SOVERSION_MAJOR})
+endif()
+
+#
+# install command to set up library install
+# given the above PUBLIC_HEADER property set, this
+# pulls along all the header files with the library.
+install(TARGETS double-conversion
+  EXPORT double-conversionLibraryDepends
+  RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin
+  LIBRARY DESTINATION "${INSTALL_LIB_DIR}/lib" COMPONENT shlib
+  ARCHIVE DESTINATION "${INSTALL_LIB_DIR}/lib" COMPONENT lib
+  PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/include/double-conversion"
+  COMPONENT dev)
diff --git a/double-conversion/src/bignum-dtoa.cc b/double-conversion/src/bignum-dtoa.cc
--- a/double-conversion/src/bignum-dtoa.cc
+++ b/double-conversion/src/bignum-dtoa.cc
@@ -192,13 +192,13 @@
     delta_plus = delta_minus;
   }
   *length = 0;
-  while (true) {
+  for (;;) {
     uint16_t digit;
     digit = numerator->DivideModuloIntBignum(*denominator);
     ASSERT(digit <= 9);  // digit is a uint16_t and therefore always positive.
     // digit = numerator / denominator (integer division).
     // numerator = numerator % denominator.
-    buffer[(*length)++] = digit + '0';
+    buffer[(*length)++] = static_cast<char>(digit + '0');
 
     // Can we stop already?
     // If the remainder of the division is less than the distance to the lower
@@ -282,7 +282,7 @@
 // exponent (decimal_point), when rounding upwards.
 static void GenerateCountedDigits(int count, int* decimal_point,
                                   Bignum* numerator, Bignum* denominator,
-                                  Vector<char>(buffer), int* length) {
+                                  Vector<char> buffer, int* length) {
   ASSERT(count >= 0);
   for (int i = 0; i < count - 1; ++i) {
     uint16_t digit;
@@ -290,7 +290,7 @@
     ASSERT(digit <= 9);  // digit is a uint16_t and therefore always positive.
     // digit = numerator / denominator (integer division).
     // numerator = numerator % denominator.
-    buffer[i] = digit + '0';
+    buffer[i] = static_cast<char>(digit + '0');
     // Prepare for next iteration.
     numerator->Times10();
   }
@@ -300,7 +300,8 @@
   if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
     digit++;
   }
-  buffer[count - 1] = digit + '0';
+  ASSERT(digit <= 10);
+  buffer[count - 1] = static_cast<char>(digit + '0');
   // Correct bad digits (in case we had a sequence of '9's). Propagate the
   // carry until we hat a non-'9' or til we reach the first digit.
   for (int i = count - 1; i > 0; --i) {
diff --git a/double-conversion/src/bignum.cc b/double-conversion/src/bignum.cc
--- a/double-conversion/src/bignum.cc
+++ b/double-conversion/src/bignum.cc
@@ -40,6 +40,7 @@
 
 template<typename S>
 static int BitSize(S value) {
+  (void) value;  // Mark variable as used.
   return 8 * sizeof(value);
 }
 
@@ -122,9 +123,8 @@
 static int HexCharValue(char c) {
   if ('0' <= c && c <= '9') return c - '0';
   if ('a' <= c && c <= 'f') return 10 + c - 'a';
-  if ('A' <= c && c <= 'F') return 10 + c - 'A';
-  UNREACHABLE();
-  return 0;  // To make compiler happy.
+  ASSERT('A' <= c && c <= 'F');
+  return 10 + c - 'A';
 }
 
 
@@ -501,13 +501,14 @@
   // Start by removing multiples of 'other' until both numbers have the same
   // number of digits.
   while (BigitLength() > other.BigitLength()) {
-    // This naive approach is extremely inefficient if the this divided other
-    // might be big. This function is implemented for doubleToString where
+    // This naive approach is extremely inefficient if `this` divided by other
+    // is big. This function is implemented for doubleToString where
     // the result should be small (less than 10).
     ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
+    ASSERT(bigits_[used_digits_ - 1] < 0x10000);
     // Remove the multiples of the first digit.
     // Example this = 23 and other equals 9. -> Remove 2 multiples.
-    result += bigits_[used_digits_ - 1];
+    result += static_cast<uint16_t>(bigits_[used_digits_ - 1]);
     SubtractTimes(other, bigits_[used_digits_ - 1]);
   }
 
@@ -523,13 +524,15 @@
     // Shortcut for easy (and common) case.
     int quotient = this_bigit / other_bigit;
     bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
-    result += quotient;
+    ASSERT(quotient < 0x10000);
+    result += static_cast<uint16_t>(quotient);
     Clamp();
     return result;
   }
 
   int division_estimate = this_bigit / (other_bigit + 1);
-  result += division_estimate;
+  ASSERT(division_estimate < 0x10000);
+  result += static_cast<uint16_t>(division_estimate);
   SubtractTimes(other, division_estimate);
 
   if (other_bigit * (division_estimate + 1) > this_bigit) {
@@ -560,8 +563,8 @@
 
 static char HexCharOfValue(int value) {
   ASSERT(0 <= value && value <= 16);
-  if (value < 10) return value + '0';
-  return value - 10 + 'A';
+  if (value < 10) return static_cast<char>(value + '0');
+  return static_cast<char>(value - 10 + 'A');
 }
 
 
@@ -755,7 +758,6 @@
     Chunk difference = bigits_[i] - borrow;
     bigits_[i] = difference & kBigitMask;
     borrow = difference >> (kChunkSize - 1);
-    ++i;
   }
   Clamp();
 }
diff --git a/double-conversion/src/cached-powers.cc b/double-conversion/src/cached-powers.cc
--- a/double-conversion/src/cached-powers.cc
+++ b/double-conversion/src/cached-powers.cc
@@ -152,6 +152,7 @@
   ASSERT(0 <= index && index < kCachedPowersLength);
   CachedPower cached_power = kCachedPowers[index];
   ASSERT(min_exponent <= cached_power.binary_exponent);
+  (void) max_exponent;  // Mark variable as used.
   ASSERT(cached_power.binary_exponent <= max_exponent);
   *decimal_exponent = cached_power.decimal_exponent;
   *power = DiyFp(cached_power.significand, cached_power.binary_exponent);
diff --git a/double-conversion/src/diy-fp.h b/double-conversion/src/diy-fp.h
--- a/double-conversion/src/diy-fp.h
+++ b/double-conversion/src/diy-fp.h
@@ -42,7 +42,7 @@
   static const int kSignificandSize = 64;
 
   DiyFp() : f_(0), e_(0) {}
-  DiyFp(uint64_t f, int e) : f_(f), e_(e) {}
+  DiyFp(uint64_t significand, int exponent) : f_(significand), e_(exponent) {}
 
   // this = this - other.
   // The exponents of both numbers must be the same and the significand of this
@@ -76,22 +76,22 @@
 
   void Normalize() {
     ASSERT(f_ != 0);
-    uint64_t f = f_;
-    int e = e_;
+    uint64_t significand = f_;
+    int exponent = e_;
 
     // This method is mainly called for normalizing boundaries. In general
     // boundaries need to be shifted by 10 bits. We thus optimize for this case.
     const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
-    while ((f & k10MSBits) == 0) {
-      f <<= 10;
-      e -= 10;
+    while ((significand & k10MSBits) == 0) {
+      significand <<= 10;
+      exponent -= 10;
     }
-    while ((f & kUint64MSB) == 0) {
-      f <<= 1;
-      e--;
+    while ((significand & kUint64MSB) == 0) {
+      significand <<= 1;
+      exponent--;
     }
-    f_ = f;
-    e_ = e;
+    f_ = significand;
+    e_ = exponent;
   }
 
   static DiyFp Normalize(const DiyFp& a) {
diff --git a/double-conversion/src/double-conversion.cc b/double-conversion/src/double-conversion.cc
--- a/double-conversion/src/double-conversion.cc
+++ b/double-conversion/src/double-conversion.cc
@@ -348,7 +348,6 @@
     case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
     default:
       UNREACHABLE();
-      return BIGNUM_DTOA_SHORTEST;  // To silence compiler.
   }
 }
 
@@ -403,8 +402,8 @@
                              vector, length, point);
       break;
     default:
-      UNREACHABLE();
       fast_worked = false;
+      UNREACHABLE();
   }
   if (fast_worked) return;
 
@@ -417,8 +416,9 @@
 
 // Consumes the given substring from the iterator.
 // Returns false, if the substring does not match.
-static bool ConsumeSubString(const char** current,
-                             const char* end,
+template <class Iterator>
+static bool ConsumeSubString(Iterator* current,
+                             Iterator end,
                              const char* substring) {
   ASSERT(**current == *substring);
   for (substring++; *substring != '\0'; substring++) {
@@ -440,10 +440,36 @@
 const int kMaxSignificantDigits = 772;
 
 
+static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
+static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
+
+
+static const uc16 kWhitespaceTable16[] = {
+  160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
+  8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
+};
+static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
+
+
+static bool isWhitespace(int x) {
+  if (x < 128) {
+    for (int i = 0; i < kWhitespaceTable7Length; i++) {
+      if (kWhitespaceTable7[i] == x) return true;
+    }
+  } else {
+    for (int i = 0; i < kWhitespaceTable16Length; i++) {
+      if (kWhitespaceTable16[i] == x) return true;
+    }
+  }
+  return false;
+}
+
+
 // Returns true if a nonspace found and false if the end has reached.
-static inline bool AdvanceToNonspace(const char** current, const char* end) {
+template <class Iterator>
+static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
   while (*current != end) {
-    if (**current != ' ') return true;
+    if (!isWhitespace(**current)) return true;
     ++*current;
   }
   return false;
@@ -462,26 +488,50 @@
 }
 
 
+// Returns true if 'c' is a decimal digit that is valid for the given radix.
+//
+// The function is small and could be inlined, but VS2012 emitted a warning
+// because it constant-propagated the radix and concluded that the last
+// condition was always true. By moving it into a separate function the
+// compiler wouldn't warn anymore.
+static bool IsDecimalDigitForRadix(int c, int radix) {
+  return '0' <= c && c <= '9' && (c - '0') < radix;
+}
+
+// Returns true if 'c' is a character digit that is valid for the given radix.
+// The 'a_character' should be 'a' or 'A'.
+//
+// The function is small and could be inlined, but VS2012 emitted a warning
+// because it constant-propagated the radix and concluded that the first
+// condition was always false. By moving it into a separate function the
+// compiler wouldn't warn anymore.
+static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
+  return radix > 10 && c >= a_character && c < a_character + radix - 10;
+}
+
+
 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
-template <int radix_log_2>
-static double RadixStringToIeee(const char* current,
-                                const char* end,
+template <int radix_log_2, class Iterator>
+static double RadixStringToIeee(Iterator* current,
+                                Iterator end,
                                 bool sign,
                                 bool allow_trailing_junk,
                                 double junk_string_value,
                                 bool read_as_double,
-                                const char** trailing_pointer) {
-  ASSERT(current != end);
+                                bool* result_is_junk) {
+  ASSERT(*current != end);
 
   const int kDoubleSize = Double::kSignificandSize;
   const int kSingleSize = Single::kSignificandSize;
   const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
 
+  *result_is_junk = true;
+
   // Skip leading 0s.
-  while (*current == '0') {
-    ++current;
-    if (current == end) {
-      *trailing_pointer = end;
+  while (**current == '0') {
+    ++(*current);
+    if (*current == end) {
+      *result_is_junk = false;
       return SignedZero(sign);
     }
   }
@@ -492,14 +542,14 @@
 
   do {
     int digit;
-    if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
-      digit = static_cast<char>(*current) - '0';
-    } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
-      digit = static_cast<char>(*current) - 'a' + 10;
-    } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
-      digit = static_cast<char>(*current) - 'A' + 10;
+    if (IsDecimalDigitForRadix(**current, radix)) {
+      digit = static_cast<char>(**current) - '0';
+    } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
+      digit = static_cast<char>(**current) - 'a' + 10;
+    } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
+      digit = static_cast<char>(**current) - 'A' + 10;
     } else {
-      if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) {
+      if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
         break;
       } else {
         return junk_string_value;
@@ -523,14 +573,14 @@
       exponent = overflow_bits_count;
 
       bool zero_tail = true;
-      while (true) {
-        ++current;
-        if (current == end || !isDigit(*current, radix)) break;
-        zero_tail = zero_tail && *current == '0';
+      for (;;) {
+        ++(*current);
+        if (*current == end || !isDigit(**current, radix)) break;
+        zero_tail = zero_tail && **current == '0';
         exponent += radix_log_2;
       }
 
-      if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
+      if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
         return junk_string_value;
       }
 
@@ -552,13 +602,13 @@
       }
       break;
     }
-    ++current;
-  } while (current != end);
+    ++(*current);
+  } while (*current != end);
 
   ASSERT(number < ((int64_t)1 << kSignificandSize));
   ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
 
-  *trailing_pointer = current;
+  *result_is_junk = false;
 
   if (exponent == 0) {
     if (sign) {
@@ -573,13 +623,14 @@
 }
 
 
+template <class Iterator>
 double StringToDoubleConverter::StringToIeee(
-    const char* input,
+    Iterator input,
     int length,
-    int* processed_characters_count,
-    bool read_as_double) {
-  const char* current = input;
-  const char* end = input + length;
+    bool read_as_double,
+    int* processed_characters_count) const {
+  Iterator current = input;
+  Iterator end = input + length;
 
   *processed_characters_count = 0;
 
@@ -600,7 +651,7 @@
 
   if (allow_leading_spaces || allow_trailing_spaces) {
     if (!AdvanceToNonspace(&current, end)) {
-      *processed_characters_count = current - input;
+      *processed_characters_count = static_cast<int>(current - input);
       return empty_string_value_;
     }
     if (!allow_leading_spaces && (input != current)) {
@@ -626,7 +677,7 @@
   if (*current == '+' || *current == '-') {
     sign = (*current == '-');
     ++current;
-    const char* next_non_space = current;
+    Iterator next_non_space = current;
     // Skip following spaces (if allowed).
     if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
     if (!allow_spaces_after_sign && (current != next_non_space)) {
@@ -649,7 +700,7 @@
       }
 
       ASSERT(buffer_pos == 0);
-      *processed_characters_count = current - input;
+      *processed_characters_count = static_cast<int>(current - input);
       return sign ? -Double::Infinity() : Double::Infinity();
     }
   }
@@ -668,7 +719,7 @@
       }
 
       ASSERT(buffer_pos == 0);
-      *processed_characters_count = current - input;
+      *processed_characters_count = static_cast<int>(current - input);
       return sign ? -Double::NaN() : Double::NaN();
     }
   }
@@ -677,7 +728,7 @@
   if (*current == '0') {
     ++current;
     if (current == end) {
-      *processed_characters_count = current - input;
+      *processed_characters_count = static_cast<int>(current - input);
       return SignedZero(sign);
     }
 
@@ -690,17 +741,17 @@
         return junk_string_value_;  // "0x".
       }
 
-      const char* tail_pointer = NULL;
-      double result = RadixStringToIeee<4>(current,
+      bool result_is_junk;
+      double result = RadixStringToIeee<4>(&current,
                                            end,
                                            sign,
                                            allow_trailing_junk,
                                            junk_string_value_,
                                            read_as_double,
-                                           &tail_pointer);
-      if (tail_pointer != NULL) {
-        if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
-        *processed_characters_count = tail_pointer - input;
+                                           &result_is_junk);
+      if (!result_is_junk) {
+        if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
+        *processed_characters_count = static_cast<int>(current - input);
       }
       return result;
     }
@@ -709,7 +760,7 @@
     while (*current == '0') {
       ++current;
       if (current == end) {
-        *processed_characters_count = current - input;
+        *processed_characters_count = static_cast<int>(current - input);
         return SignedZero(sign);
       }
     }
@@ -757,7 +808,7 @@
       while (*current == '0') {
         ++current;
         if (current == end) {
-          *processed_characters_count = current - input;
+          *processed_characters_count = static_cast<int>(current - input);
           return SignedZero(sign);
         }
         exponent--;  // Move this 0 into the exponent.
@@ -801,9 +852,9 @@
         return junk_string_value_;
       }
     }
-    char sign = '+';
+    char exponen_sign = '+';
     if (*current == '+' || *current == '-') {
-      sign = static_cast<char>(*current);
+      exponen_sign = static_cast<char>(*current);
       ++current;
       if (current == end) {
         if (allow_trailing_junk) {
@@ -837,7 +888,7 @@
       ++current;
     } while (current != end && *current >= '0' && *current <= '9');
 
-    exponent += (sign == '-' ? -num : num);
+    exponent += (exponen_sign == '-' ? -num : num);
   }
 
   if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
@@ -855,16 +906,17 @@
 
   if (octal) {
     double result;
-    const char* tail_pointer = NULL;
-    result = RadixStringToIeee<3>(buffer,
+    bool result_is_junk;
+    char* start = buffer;
+    result = RadixStringToIeee<3>(&start,
                                   buffer + buffer_pos,
                                   sign,
                                   allow_trailing_junk,
                                   junk_string_value_,
                                   read_as_double,
-                                  &tail_pointer);
-    ASSERT(tail_pointer != NULL);
-    *processed_characters_count = current - input;
+                                  &result_is_junk);
+    ASSERT(!result_is_junk);
+    *processed_characters_count = static_cast<int>(current - input);
     return result;
   }
 
@@ -882,8 +934,42 @@
   } else {
     converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
   }
-  *processed_characters_count = current - input;
+  *processed_characters_count = static_cast<int>(current - input);
   return sign? -converted: converted;
+}
+
+
+double StringToDoubleConverter::StringToDouble(
+    const char* buffer,
+    int length,
+    int* processed_characters_count) const {
+  return StringToIeee(buffer, length, true, processed_characters_count);
+}
+
+
+double StringToDoubleConverter::StringToDouble(
+    const uc16* buffer,
+    int length,
+    int* processed_characters_count) const {
+  return StringToIeee(buffer, length, true, processed_characters_count);
+}
+
+
+float StringToDoubleConverter::StringToFloat(
+    const char* buffer,
+    int length,
+    int* processed_characters_count) const {
+  return static_cast<float>(StringToIeee(buffer, length, false,
+                                         processed_characters_count));
+}
+
+
+float StringToDoubleConverter::StringToFloat(
+    const uc16* buffer,
+    int length,
+    int* processed_characters_count) const {
+  return static_cast<float>(StringToIeee(buffer, length, false,
+                                         processed_characters_count));
 }
 
 }  // namespace double_conversion
diff --git a/double-conversion/src/double-conversion.h b/double-conversion/src/double-conversion.h
--- a/double-conversion/src/double-conversion.h
+++ b/double-conversion/src/double-conversion.h
@@ -415,9 +415,10 @@
   //          junk, too.
   //  - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
   //      a double literal.
-  //  - ALLOW_LEADING_SPACES: skip over leading spaces.
-  //  - ALLOW_TRAILING_SPACES: ignore trailing spaces.
-  //  - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign.
+  //  - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces,
+  //                          new-lines, and tabs.
+  //  - ALLOW_TRAILING_SPACES: ignore trailing whitespace.
+  //  - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
   //       Ex: StringToDouble("-   123.2") -> -123.2.
   //           StringToDouble("+   123.2") -> 123.2
   //
@@ -502,20 +503,25 @@
   // in the 'processed_characters_count'. Trailing junk is never included.
   double StringToDouble(const char* buffer,
                         int length,
-                        int* processed_characters_count) {
-    return StringToIeee(buffer, length, processed_characters_count, true);
-  }
+                        int* processed_characters_count) const;
 
+  // Same as StringToDouble above but for 16 bit characters.
+  double StringToDouble(const uc16* buffer,
+                        int length,
+                        int* processed_characters_count) const;
+
   // Same as StringToDouble but reads a float.
   // Note that this is not equivalent to static_cast<float>(StringToDouble(...))
   // due to potential double-rounding.
   float StringToFloat(const char* buffer,
                       int length,
-                      int* processed_characters_count) {
-    return static_cast<float>(StringToIeee(buffer, length,
-                                           processed_characters_count, false));
-  }
+                      int* processed_characters_count) const;
 
+  // Same as StringToFloat above but for 16 bit characters.
+  float StringToFloat(const uc16* buffer,
+                      int length,
+                      int* processed_characters_count) const;
+
  private:
   const int flags_;
   const double empty_string_value_;
@@ -523,10 +529,11 @@
   const char* const infinity_symbol_;
   const char* const nan_symbol_;
 
-  double StringToIeee(const char* buffer,
+  template <class Iterator>
+  double StringToIeee(Iterator start_pointer,
                       int length,
-                      int* processed_characters_count,
-                      bool read_as_double);
+                      bool read_as_double,
+                      int* processed_characters_count) const;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
 };
diff --git a/double-conversion/src/fast-dtoa.cc b/double-conversion/src/fast-dtoa.cc
--- a/double-conversion/src/fast-dtoa.cc
+++ b/double-conversion/src/fast-dtoa.cc
@@ -248,10 +248,7 @@
   // Note: kPowersOf10[i] == 10^(i-1).
   exponent_plus_one_guess++;
   // We don't have any guarantees that 2^number_bits <= number.
-  // TODO(floitsch): can we change the 'while' into an 'if'? We definitely see
-  // number < (2^number_bits - 1), but I haven't encountered
-  // number < (2^number_bits - 2) yet.
-  while (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
+  if (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
     exponent_plus_one_guess--;
   }
   *power = kSmallPowersOfTen[exponent_plus_one_guess];
@@ -350,7 +347,8 @@
   // that is smaller than integrals.
   while (*kappa > 0) {
     int digit = integrals / divisor;
-    buffer[*length] = '0' + digit;
+    ASSERT(digit <= 9);
+    buffer[*length] = static_cast<char>('0' + digit);
     (*length)++;
     integrals %= divisor;
     (*kappa)--;
@@ -379,13 +377,14 @@
   ASSERT(one.e() >= -60);
   ASSERT(fractionals < one.f());
   ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
-  while (true) {
+  for (;;) {
     fractionals *= 10;
     unit *= 10;
     unsafe_interval.set_f(unsafe_interval.f() * 10);
     // Integer division by one.
     int digit = static_cast<int>(fractionals >> -one.e());
-    buffer[*length] = '0' + digit;
+    ASSERT(digit <= 9);
+    buffer[*length] = static_cast<char>('0' + digit);
     (*length)++;
     fractionals &= one.f() - 1;  // Modulo by one.
     (*kappa)--;
@@ -459,7 +458,8 @@
   // that is smaller than 'integrals'.
   while (*kappa > 0) {
     int digit = integrals / divisor;
-    buffer[*length] = '0' + digit;
+    ASSERT(digit <= 9);
+    buffer[*length] = static_cast<char>('0' + digit);
     (*length)++;
     requested_digits--;
     integrals %= divisor;
@@ -492,7 +492,8 @@
     w_error *= 10;
     // Integer division by one.
     int digit = static_cast<int>(fractionals >> -one.e());
-    buffer[*length] = '0' + digit;
+    ASSERT(digit <= 9);
+    buffer[*length] = static_cast<char>('0' + digit);
     (*length)++;
     requested_digits--;
     fractionals &= one.f() - 1;  // Modulo by one.
diff --git a/double-conversion/src/fixed-dtoa.cc b/double-conversion/src/fixed-dtoa.cc
--- a/double-conversion/src/fixed-dtoa.cc
+++ b/double-conversion/src/fixed-dtoa.cc
@@ -133,7 +133,7 @@
   while (number != 0) {
     int digit = number % 10;
     number /= 10;
-    buffer[(*length) + number_length] = '0' + digit;
+    buffer[(*length) + number_length] = static_cast<char>('0' + digit);
     number_length++;
   }
   // Exchange the digits.
@@ -150,7 +150,7 @@
 }
 
 
-static void FillDigits64FixedLength(uint64_t number, int requested_length,
+static void FillDigits64FixedLength(uint64_t number,
                                     Vector<char> buffer, int* length) {
   const uint32_t kTen7 = 10000000;
   // For efficiency cut the number into 3 uint32_t parts, and print those.
@@ -253,7 +253,8 @@
       fractionals *= 5;
       point--;
       int digit = static_cast<int>(fractionals >> point);
-      buffer[*length] = '0' + digit;
+      ASSERT(digit <= 9);
+      buffer[*length] = static_cast<char>('0' + digit);
       (*length)++;
       fractionals -= static_cast<uint64_t>(digit) << point;
     }
@@ -274,7 +275,8 @@
       fractionals128.Multiply(5);
       point--;
       int digit = fractionals128.DivModPowerOf2(point);
-      buffer[*length] = '0' + digit;
+      ASSERT(digit <= 9);
+      buffer[*length] = static_cast<char>('0' + digit);
       (*length)++;
     }
     if (fractionals128.BitAt(point - 1) == 1) {
@@ -358,7 +360,7 @@
       remainder = (dividend % divisor) << exponent;
     }
     FillDigits32(quotient, buffer, length);
-    FillDigits64FixedLength(remainder, divisor_power, buffer, length);
+    FillDigits64FixedLength(remainder, buffer, length);
     *decimal_point = *length;
   } else if (exponent >= 0) {
     // 0 <= exponent <= 11
diff --git a/double-conversion/src/ieee.h b/double-conversion/src/ieee.h
--- a/double-conversion/src/ieee.h
+++ b/double-conversion/src/ieee.h
@@ -256,6 +256,8 @@
     return (significand & kSignificandMask) |
         (biased_exponent << kPhysicalSignificandSize);
   }
+
+  DISALLOW_COPY_AND_ASSIGN(Double);
 };
 
 class Single {
@@ -391,6 +393,8 @@
   static const uint32_t kNaN = 0x7FC00000;
 
   const uint32_t d32_;
+
+  DISALLOW_COPY_AND_ASSIGN(Single);
 };
 
 }  // namespace double_conversion
diff --git a/double-conversion/src/strtod.cc b/double-conversion/src/strtod.cc
--- a/double-conversion/src/strtod.cc
+++ b/double-conversion/src/strtod.cc
@@ -137,6 +137,7 @@
   Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
   exponent += left_trimmed.length() - right_trimmed.length();
   if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
+    (void) space_size;  // Mark variable as used.
     ASSERT(space_size >= kMaxSignificantDecimalDigits);
     CutToMaxSignificantDigits(right_trimmed, exponent,
                               buffer_copy_space, updated_exponent);
@@ -263,7 +264,6 @@
     case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
     default:
       UNREACHABLE();
-      return DiyFp(0, 0);
   }
 }
 
@@ -286,7 +286,7 @@
   const int kDenominator = 1 << kDenominatorLog;
   // Move the remaining decimals into the exponent.
   exponent += remaining_decimals;
-  int error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
+  uint64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
 
   int old_e = input.e();
   input.Normalize();
@@ -515,6 +515,7 @@
     double double_next2 = Double(double_next).NextDouble();
     f4 = static_cast<float>(double_next2);
   }
+  (void) f2;  // Mark variable as used.
   ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
 
   // If the guess doesn't lie near a single-precision boundary we can simply
diff --git a/double-conversion/src/utils.h b/double-conversion/src/utils.h
--- a/double-conversion/src/utils.h
+++ b/double-conversion/src/utils.h
@@ -33,7 +33,8 @@
 
 #include <assert.h>
 #ifndef ASSERT
-#define ASSERT(condition)      (assert(condition))
+#define ASSERT(condition)         \
+    assert(condition);
 #endif
 #ifndef UNIMPLEMENTED
 #define UNIMPLEMENTED() (abort())
@@ -55,11 +56,15 @@
 #if defined(_M_X64) || defined(__x86_64__) || \
     defined(__ARMEL__) || defined(__avr32__) || \
     defined(__hppa__) || defined(__ia64__) || \
-    defined(__mips__) || defined(__powerpc__) || \
+    defined(__mips__) || \
+    defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
     defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
     defined(__SH4__) || defined(__alpha__) || \
-    defined(_MIPS_ARCH_MIPS32R2)
+    defined(_MIPS_ARCH_MIPS32R2) || \
+    defined(__AARCH64EL__)
 #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
+#elif defined(__mc68000__)
+#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
 #elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
 #if defined(_WIN32)
 // Windows uses a 64bit wide floating point stack.
@@ -71,6 +76,11 @@
 #error Target architecture was not detected as supported by Double-Conversion.
 #endif
 
+#if defined(__GNUC__)
+#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
+#else
+#define DOUBLE_CONVERSION_UNUSED
+#endif
 
 #if defined(_WIN32) && !defined(__MINGW32__)
 
@@ -90,6 +100,8 @@
 
 #endif
 
+typedef uint16_t uc16;
+
 // The following macro works on both 32 and 64-bit platforms.
 // Usage: instead of writing 0x1234567890123456
 //      write UINT64_2PART_C(0x12345678,90123456);
@@ -155,8 +167,8 @@
 class Vector {
  public:
   Vector() : start_(NULL), length_(0) {}
-  Vector(T* data, int length) : start_(data), length_(length) {
-    ASSERT(length == 0 || (length > 0 && data != NULL));
+  Vector(T* data, int len) : start_(data), length_(len) {
+    ASSERT(len == 0 || (len > 0 && data != NULL));
   }
 
   // Returns a vector using the same backing storage as this one,
@@ -198,8 +210,8 @@
 // buffer bounds on all operations in debug mode.
 class StringBuilder {
  public:
-  StringBuilder(char* buffer, int size)
-      : buffer_(buffer, size), position_(0) { }
+  StringBuilder(char* buffer, int buffer_size)
+      : buffer_(buffer, buffer_size), position_(0) { }
 
   ~StringBuilder() { if (!is_finalized()) Finalize(); }
 
@@ -296,7 +308,8 @@
 inline Dest BitCast(const Source& source) {
   // Compile time assertion: sizeof(Dest) == sizeof(Source)
   // A compile error here means your Dest and Source have different sizes.
-  typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
+  DOUBLE_CONVERSION_UNUSED
+      typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
 
   Dest dest;
   memmove(&dest, &source, sizeof(dest));
diff --git a/double-conversion/test/CMakeLists.txt b/double-conversion/test/CMakeLists.txt
new file mode 100644
--- /dev/null
+++ b/double-conversion/test/CMakeLists.txt
@@ -0,0 +1,1 @@
+add_subdirectory(cctest)
diff --git a/double-conversion/test/cctest/CMakeLists.txt b/double-conversion/test/cctest/CMakeLists.txt
new file mode 100644
--- /dev/null
+++ b/double-conversion/test/cctest/CMakeLists.txt
@@ -0,0 +1,50 @@
+
+set(CCTEST_SRC
+  cctest.cc
+  gay-fixed.cc
+  gay-precision.cc
+  gay-shortest.cc
+  gay-shortest-single.cc
+  test-bignum.cc
+  test-bignum-dtoa.cc
+  test-conversions.cc
+  test-diy-fp.cc
+  test-dtoa.cc
+  test-fast-dtoa.cc
+  test-fixed-dtoa.cc
+  test-ieee.cc
+  test-strtod.cc
+)
+
+add_executable(cctest ${CCTEST_SRC})
+target_link_libraries(cctest double-conversion)
+
+add_test(NAME test_bignum
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-bignum)
+
+add_test(NAME test_bignum_dtoa
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-bignum-dtoa)
+
+add_test(NAME test_conversions
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-conversions)
+add_test(NAME test_diy_fp
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-diy-fp)
+add_test(NAME test_dtoa
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-dtoa)
+add_test(NAME test_fast_dtoa
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-fast-dtoa)
+add_test(NAME test_fixed_dtoa
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-fixed-dtoa)
+add_test(NAME test_ieee
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-ieee)
+add_test(NAME test_strtod
+  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+  COMMAND $<TARGET_FILE:cctest> test-strtod)
diff --git a/double-conversion/test/cctest/cctest.cc b/double-conversion/test/cctest/cctest.cc
--- a/double-conversion/test/cctest/cctest.cc
+++ b/double-conversion/test/cctest/cctest.cc
@@ -34,16 +34,18 @@
 CcTest* CcTest::last_ = NULL;
 
 
-CcTest::CcTest(TestFunction* callback, const char* file, const char* name,
-               const char* dependency, bool enabled)
-    : callback_(callback), name_(name), dependency_(dependency), prev_(last_) {
+CcTest::CcTest(TestFunction* callback, const char* test_file,
+               const char* test_name, const char* test_dependency,
+               bool test_is_enabled)
+    : callback_(callback), name_(test_name), dependency_(test_dependency),
+      prev_(last_) {
   // Find the base name of this test (const_cast required on Windows).
-  char *basename = strrchr(const_cast<char *>(file), '/');
+  char *basename = strrchr(const_cast<char *>(test_file), '/');
   if (!basename) {
-    basename = strrchr(const_cast<char *>(file), '\\');
+    basename = strrchr(const_cast<char *>(test_file), '\\');
   }
   if (!basename) {
-    basename = strdup(file);
+    basename = strdup(test_file);
   } else {
     basename = strdup(basename + 1);
   }
@@ -52,7 +54,7 @@
   if (extension) *extension = 0;
   // Install this test in the list of tests
   file_ = basename;
-  enabled_ = enabled;
+  enabled_ = test_is_enabled;
   prev_ = last_;
   last_ = this;
 }
diff --git a/double-conversion/test/cctest/test-bignum-dtoa.cc b/double-conversion/test/cctest/test-bignum-dtoa.cc
--- a/double-conversion/test/cctest/test-bignum-dtoa.cc
+++ b/double-conversion/test/cctest/test-bignum-dtoa.cc
@@ -282,7 +282,7 @@
   CHECK_EQ("332307", buffer.start());
   CHECK_EQ(36, point);
 
-  BignumDtoa(1.23405349260765015351e-41f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
+  BignumDtoa(1.2341e-41f, BIGNUM_DTOA_SHORTEST_SINGLE, 0,
              buffer, &length, &point);
   CHECK_EQ("12341", buffer.start());
   CHECK_EQ(-40, point);
diff --git a/double-conversion/test/cctest/test-conversions.cc b/double-conversion/test/cctest/test-conversions.cc
--- a/double-conversion/test/cctest/test-conversions.cc
+++ b/double-conversion/test/cctest/test-conversions.cc
@@ -1718,6 +1718,18 @@
 }
 
 
+static double StrToD16(const uc16* str16, int length, int flags,
+                       double empty_string_value,
+                       int* processed_characters_count, bool* processed_all) {
+  StringToDoubleConverter converter(flags, empty_string_value, Double::NaN(),
+                                    NULL, NULL);
+  double result =
+      converter.StringToDouble(str16, length, processed_characters_count);
+  *processed_all = (length == *processed_characters_count);
+  return result;
+}
+
+
 static double StrToD(const char* str, int flags, double empty_string_value,
                      int* processed_characters_count, bool* processed_all) {
   StringToDoubleConverter converter(flags, empty_string_value, Double::NaN(),
@@ -1726,6 +1738,19 @@
                                            processed_characters_count);
   *processed_all =
       ((strlen(str) == static_cast<unsigned>(*processed_characters_count)));
+
+  uc16 buffer16[256];
+  ASSERT(strlen(str) < ARRAY_SIZE(buffer16));
+  int len = strlen(str);
+  for (int i = 0; i < len; i++) {
+    buffer16[i] = str[i];
+  }
+  int processed_characters_count16;
+  bool processed_all16;
+  double result16 = StrToD16(buffer16, len, flags, empty_string_value,
+                             &processed_characters_count16, &processed_all16);
+  CHECK_EQ(result, result16);
+  CHECK_EQ(*processed_characters_count, processed_characters_count16);
   return result;
 }
 
@@ -2530,12 +2555,21 @@
   CHECK_EQ(10.0, StrToD(" 012", flags, 0.0, &processed, &all_used));
   CHECK(all_used);
 
+  CHECK_EQ(10.0, StrToD("\n012", flags, 0.0, &processed, &all_used));
+  CHECK(all_used);
+
   CHECK_EQ(0.0, StrToD(" 00", flags, 1.0, &processed, &all_used));
   CHECK(all_used);
 
+  CHECK_EQ(0.0, StrToD("\t00", flags, 1.0, &processed, &all_used));
+  CHECK(all_used);
+
   CHECK_EQ(10.0, StrToD(" 012", flags, 1.0, &processed, &all_used));
   CHECK(all_used);
 
+  CHECK_EQ(10.0, StrToD("\n012", flags, 1.0, &processed, &all_used));
+  CHECK(all_used);
+
   CHECK_EQ(123456789.0,
            StrToD(" 0123456789", flags, Double::NaN(), &processed, &all_used));
   CHECK(all_used);
@@ -2545,6 +2579,10 @@
   CHECK(all_used);
 
   CHECK_EQ(342391.0,
+           StrToD("\n01234567", flags, Double::NaN(), &processed, &all_used));
+  CHECK(all_used);
+
+  CHECK_EQ(342391.0,
            StrToD(" + 01234567", flags, Double::NaN(), &processed, &all_used));
   CHECK(all_used);
 
@@ -2552,6 +2590,10 @@
            StrToD(" - 01234567", flags, Double::NaN(), &processed, &all_used));
   CHECK(all_used);
 
+  CHECK_EQ(-342391.0,
+           StrToD("\n-\t01234567", flags, Double::NaN(), &processed, &all_used));
+  CHECK(all_used);
+
   CHECK_EQ(10.0, StrToD(" 012 ", flags, 0.0, &processed, &all_used));
   CHECK(all_used);
 
@@ -3196,14 +3238,41 @@
 }
 
 
-static float StrToF(const char* str, int flags, float empty_string_value,
-                    int* processed_characters_count, bool* processed_all) {
+static float StrToF16(const uc16* str16, int length, int flags,
+                      double empty_string_value,
+                      int* processed_characters_count,
+                      bool* processed_all) {
+  StringToDoubleConverter converter(flags, empty_string_value, Double::NaN(),
+                                    NULL, NULL);
+  double result =
+      converter.StringToFloat(str16, length, processed_characters_count);
+  *processed_all = (length == *processed_characters_count);
+  return result;
+}
+
+
+static double StrToF(const char* str, int flags, double empty_string_value,
+                     int* processed_characters_count, bool* processed_all) {
   StringToDoubleConverter converter(flags, empty_string_value, Single::NaN(),
                                     NULL, NULL);
   float result = converter.StringToFloat(str, strlen(str),
                                          processed_characters_count);
   *processed_all =
       ((strlen(str) == static_cast<unsigned>(*processed_characters_count)));
+
+  uc16 buffer16[256];
+  ASSERT(strlen(str) < ARRAY_SIZE(buffer16));
+  int len = strlen(str);
+  for (int i = 0; i < len; i++) {
+    buffer16[i] = str[i];
+  }
+  int processed_characters_count16;
+  bool processed_all16;
+  float result16 = StrToF16(buffer16, len, flags, empty_string_value,
+                            &processed_characters_count16,
+                            &processed_all16);
+  CHECK_EQ(result, result16);
+  CHECK_EQ(*processed_characters_count, processed_characters_count16);
   return result;
 }
 
@@ -4568,4 +4637,76 @@
     CHECK_EQ(1.0f, converter.StringToDouble("1234.0", 6, &processed));
     CHECK_EQ(0, processed);
   }
+}
+
+
+TEST(StringToDoubleFloatWhitespace) {
+  int flags;
+  int processed;
+  bool all_used;
+
+  flags = StringToDoubleConverter::ALLOW_LEADING_SPACES |
+      StringToDoubleConverter::ALLOW_TRAILING_SPACES |
+      StringToDoubleConverter::ALLOW_SPACES_AFTER_SIGN;
+
+  const char kWhitespaceAscii[] = {
+    0x0A, 0x0D, 0x09, 0x0B, 0x0C, 0x20,
+    '-',
+    0x0A, 0x0D, 0x09, 0x0B, 0x0C, 0x20,
+    '1', '.', '2',
+    0x0A, 0x0D, 0x09, 0x0B, 0x0C, 0x20,
+    0x00
+  };
+  CHECK_EQ(-1.2, StrToD(kWhitespaceAscii, flags, Double::NaN(),
+                        &processed, &all_used));
+  CHECK(all_used);
+  CHECK_EQ(-1.2f, StrToF(kWhitespaceAscii, flags, Double::NaN(),
+                         &processed, &all_used));
+  CHECK(all_used);
+
+  const uc16 kOghamSpaceMark = 0x1680;
+  const uc16 kMongolianVowelSeparator = 0x180E;
+  const uc16 kEnQuad = 0x2000;
+  const uc16 kEmQuad = 0x2001;
+  const uc16 kEnSpace = 0x2002;
+  const uc16 kEmSpace = 0x2003;
+  const uc16 kThreePerEmSpace = 0x2004;
+  const uc16 kFourPerEmSpace = 0x2005;
+  const uc16 kSixPerEmSpace = 0x2006;
+  const uc16 kFigureSpace = 0x2007;
+  const uc16 kPunctuationSpace = 0x2008;
+  const uc16 kThinSpace = 0x2009;
+  const uc16 kHairSpace = 0x200A;
+  const uc16 kNarrowNoBreakSpace = 0x202F;
+  const uc16 kMediumMathematicalSpace = 0x205F;
+  const uc16 kIdeographicSpace = 0x3000;
+
+  const uc16 kWhitespace16[] = {
+    0x0A, 0x0D, 0x09, 0x0B, 0x0C, 0x20, 0xA0, 0xFEFF,
+    kOghamSpaceMark, kMongolianVowelSeparator, kEnQuad, kEmQuad,
+    kEnSpace, kEmSpace, kThreePerEmSpace, kFourPerEmSpace, kSixPerEmSpace,
+    kFigureSpace, kPunctuationSpace, kThinSpace, kHairSpace,
+    kNarrowNoBreakSpace, kMediumMathematicalSpace, kIdeographicSpace,
+    '-',
+    0x0A, 0x0D, 0x09, 0x0B, 0x0C, 0x20, 0xA0, 0xFEFF,
+    kOghamSpaceMark, kMongolianVowelSeparator, kEnQuad, kEmQuad,
+    kEnSpace, kEmSpace, kThreePerEmSpace, kFourPerEmSpace, kSixPerEmSpace,
+    kFigureSpace, kPunctuationSpace, kThinSpace, kHairSpace,
+    kNarrowNoBreakSpace, kMediumMathematicalSpace, kIdeographicSpace,
+    '1', '.', '2',
+    0x0A, 0x0D, 0x09, 0x0B, 0x0C, 0x20, 0xA0, 0xFEFF,
+    kOghamSpaceMark, kMongolianVowelSeparator, kEnQuad, kEmQuad,
+    kEnSpace, kEmSpace, kThreePerEmSpace, kFourPerEmSpace, kSixPerEmSpace,
+    kFigureSpace, kPunctuationSpace, kThinSpace, kHairSpace,
+    kNarrowNoBreakSpace, kMediumMathematicalSpace, kIdeographicSpace,
+  };
+  const int kWhitespace16Length = ARRAY_SIZE(kWhitespace16);
+  CHECK_EQ(-1.2, StrToD16(kWhitespace16, kWhitespace16Length, flags,
+                          Double::NaN(),
+                          &processed, &all_used));
+  CHECK(all_used);
+  CHECK_EQ(-1.2f, StrToF16(kWhitespace16, kWhitespace16Length, flags,
+                           Single::NaN(),
+                           &processed, &all_used));
+  CHECK(all_used);
 }
diff --git a/double-conversion/test/cctest/test-fast-dtoa.cc b/double-conversion/test/cctest/test-fast-dtoa.cc
--- a/double-conversion/test/cctest/test-fast-dtoa.cc
+++ b/double-conversion/test/cctest/test-fast-dtoa.cc
@@ -32,7 +32,7 @@
   Vector<char> buffer(buffer_container, kBufferSize);
   int length;
   int point;
-  int status;
+  bool status;
 
   double min_double = 5e-324;
   status = FastDtoa(min_double, FAST_DTOA_SHORTEST, 0,
@@ -102,7 +102,7 @@
   Vector<char> buffer(buffer_container, kBufferSize);
   int length;
   int point;
-  int status;
+  bool status;
 
   float min_float = 1e-45f;
   status = FastDtoa(min_float, FAST_DTOA_SHORTEST_SINGLE, 0,
@@ -131,7 +131,7 @@
   CHECK_EQ("332307", buffer.start());
   CHECK_EQ(36, point);
 
-  status = FastDtoa(1.23405349260765015351e-41f, FAST_DTOA_SHORTEST_SINGLE, 0,
+  status = FastDtoa(1.2341e-41f, FAST_DTOA_SHORTEST_SINGLE, 0,
                     buffer, &length, &point);
   CHECK(status);
   CHECK_EQ("12341", buffer.start());
@@ -178,7 +178,7 @@
   Vector<char> buffer(buffer_container, kBufferSize);
   int length;
   int point;
-  int status;
+  bool status;
 
   status = FastDtoa(1.0, FAST_DTOA_PRECISION, 3, buffer, &length, &point);
   CHECK(status);
diff --git a/double-conversion/test/cctest/test-strtod.cc b/double-conversion/test/cctest/test-strtod.cc
--- a/double-conversion/test/cctest/test-strtod.cc
+++ b/double-conversion/test/cctest/test-strtod.cc
@@ -515,8 +515,8 @@
   CHECK_EQ(3401e34f, StrtofChar("00000340100000", 29));
   CHECK_EQ(Single::Infinity(), StrtofChar("00000341000000", 30));
   CHECK_EQ(34e37f, StrtofChar("000003400000", 32));
-  CHECK_EQ(3.4028235676e+38f, StrtofChar("34028235676", 28));
-  CHECK_EQ(3.4028235677e+38f, StrtofChar("34028235677", 28));
+  CHECK_EQ(3.4028234e+38f, StrtofChar("34028235676", 28));
+  CHECK_EQ(3.4028234e+38f, StrtofChar("34028235677", 28));
   CHECK_EQ(Single::Infinity(), StrtofChar("34028235678", 28));
 
   // The following number is the result of 89255.0/1e-22. Both floating-point
@@ -538,7 +538,12 @@
   // Verify that we don't double round.
   // Get the boundary of the boundary.
   CHECK_EQ(2.1665680640000002384185791015625e9, 2166568064.0);
+  // Visual Studio gets this wrong and believes that these two numbers are the
+  // same doubles. We want to test our conversion and not the compiler. We
+  // therefore disable the check.
+#ifndef _MSC_VER
   CHECK(2.16656806400000023841857910156251e9 != 2166568064.0);
+#endif
   CHECK_EQ(2166568192.0f, StrtofChar("21665680640000002384185791015625", -22));
 
   // 0x4fffffff = 8589934080
@@ -551,8 +556,13 @@
   CHECK_EQ(8589934592.0f, StrtofChar("858993433600001", -5));
   // Verify that we don't double round.
   // Get the boundary of the boundary.
+  // Visual Studio gets this wrong. To avoid failing tests because of a broken
+  // compiler we disable the following two tests. They were only testing the
+  // compiler. The real test is still active.
+#ifndef _MSC_VER
   CHECK_EQ(8.589934335999999523162841796875e+09, 8589934336.0);
   CHECK(8.5899343359999995231628417968749e+09 != 8589934336.0);
+#endif
   CHECK_EQ(8589934080.0f, StrtofChar("8589934335999999523162841796875", -21));
 
   // 0x4f000000 = 2147483648
@@ -649,7 +659,7 @@
     for (int i = 0; i < kShortStrtodRandomCount; ++i) {
       int pos = 0;
       for (int j = 0; j < length; ++j) {
-        buffer[pos++] = random() % 10 + '0';
+        buffer[pos++] = DeterministicRandom() % 10 + '0';
       }
       int exponent = DeterministicRandom() % (25*2 + 1) - 25 - length;
       buffer[pos] = '\0';
@@ -662,7 +672,7 @@
     for (int i = 0; i < kLargeStrtodRandomCount; ++i) {
       int pos = 0;
       for (int j = 0; j < length; ++j) {
-        buffer[pos++] = random() % 10 + '0';
+        buffer[pos++] = DeterministicRandom() % 10 + '0';
       }
       int exponent = DeterministicRandom() % (308*2 + 1) - 308 - length;
       buffer[pos] = '\0';
@@ -716,7 +726,7 @@
     for (int i = 0; i < kShortStrtofRandomCount; ++i) {
       int pos = 0;
       for (int j = 0; j < length; ++j) {
-        buffer[pos++] = random() % 10 + '0';
+        buffer[pos++] = DeterministicRandom() % 10 + '0';
       }
       int exponent = DeterministicRandom() % (5*2 + 1) - 5 - length;
       buffer[pos] = '\0';
@@ -729,7 +739,7 @@
     for (int i = 0; i < kLargeStrtofRandomCount; ++i) {
       int pos = 0;
       for (int j = 0; j < length; ++j) {
-        buffer[pos++] = random() % 10 + '0';
+        buffer[pos++] = DeterministicRandom() % 10 + '0';
       }
       int exponent = DeterministicRandom() % (38*2 + 1) - 38 - length;
       buffer[pos] = '\0';
