Merge commit '66ff69dafcb1bdaa7925a966ee1ede05e4f68778' as 'third_party/google-glog'

Change-Id: I6b90bc4d3457fa69bed66c17e68e160490a645f9
diff --git a/WORKSPACE b/WORKSPACE
index 1829355..58bac82 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -313,3 +313,8 @@
     name = "com_google_protobuf",
     path = "third_party/protobuf",
 )
+
+local_repository(
+    name = "com_github_google_glog",
+    path = "third_party/google-glog",
+)
diff --git a/third_party/google-glog/.bazelci/presubmit.yml b/third_party/google-glog/.bazelci/presubmit.yml
new file mode 100644
index 0000000..dd13f44
--- /dev/null
+++ b/third_party/google-glog/.bazelci/presubmit.yml
@@ -0,0 +1,17 @@
+---
+platforms:
+  ubuntu1404:
+    build_targets:
+    - "..."
+    test_targets:
+    - "..."
+  ubuntu1604:
+    build_targets:
+    - "..."
+    test_targets:
+    - "..."
+  macos:
+    build_targets:
+    - "..."
+    test_targets:
+    - "..."
diff --git a/third_party/google-glog/.gitignore b/third_party/google-glog/.gitignore
new file mode 100644
index 0000000..76d251f
--- /dev/null
+++ b/third_party/google-glog/.gitignore
@@ -0,0 +1,12 @@
+autom4te.cache
+glog-*.tar.gz
+packages/rpm-unknown
+packages/debian-*
+CMakeCache.txt
+CMakeFiles/
+*.cmake
+config.h
+*.sln
+*.vcxproj
+*.filters
+bazel-*
diff --git a/third_party/google-glog/.travis.ubuntu.sh b/third_party/google-glog/.travis.ubuntu.sh
new file mode 100755
index 0000000..1043f31
--- /dev/null
+++ b/third_party/google-glog/.travis.ubuntu.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e
+set -x
+
+uname -a
+
+cmake -H. -B_build_${TOOLCHAIN} -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/${TOOLCHAIN}.cmake"
+cmake --build _build_${TOOLCHAIN} -- -j4
+
+if [ "$RUN_TESTS" = true ]; then
+	case "$TOOLCHAIN" in linux-mingw*)
+		echo "copy runtime libraries needed for tests into build directory"
+		cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll /usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/{libstdc++-6.dll,libgcc_s_seh-1.dll} _build_${TOOLCHAIN}
+	esac
+	CTEST_OUTPUT_ON_FAILURE=1 cmake --build _build_${TOOLCHAIN} --target test
+fi
+
+
diff --git a/third_party/google-glog/.travis.yml b/third_party/google-glog/.travis.yml
new file mode 100644
index 0000000..911fa5e
--- /dev/null
+++ b/third_party/google-glog/.travis.yml
@@ -0,0 +1,119 @@
+sudo: required
+language: bash
+services:
+  - docker
+
+# define the build matrix
+env:
+  global:
+    - PROJECT_DIR: .
+    - TOOLCHAIN: gcc-cxx11
+    - BUILD_PACKAGES: cmake
+    - RUN_TESTS: true
+
+matrix:
+  include:
+    # Linux {
+
+    #   Ubuntu 14.04
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=trusty
+        BUILD_ARCH=amd64
+        BUILD_PACKAGES=cmake3
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=trusty
+        BUILD_ARCH=i386
+        BUILD_PACKAGES=cmake3
+    #   Ubuntu 16.04
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=xenial
+        BUILD_ARCH=amd64
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=xenial
+        BUILD_ARCH=i386
+    #   Ubuntu 18.04
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=bionic
+        BUILD_ARCH=amd64
+        TOOLCHAIN=gcc-cxx98
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=bionic
+        BUILD_ARCH=amd64
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=bionic
+        BUILD_ARCH=amd64
+        TOOLCHAIN=gcc-gnuxx11
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=bionic
+        BUILD_ARCH=amd64
+        TOOLCHAIN=gcc-cxx17
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=bionic
+        BUILD_ARCH=amd64
+        TOOLCHAIN=clang-cxx17
+        BUILD_PACKAGES="cmake clang"
+    # } // end Linux
+
+    # Windows build with mingw-w64 on Ubuntu 18.04
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=bionic
+        BUILD_ARCH=amd64
+        TOOLCHAIN=linux-mingw-w64-cxx11
+        BUILD_PACKAGES="cmake mingw-w64 wine-stable"
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=bionic
+        BUILD_ARCH=amd64
+        TOOLCHAIN=linux-mingw-w64-gnuxx11
+        BUILD_PACKAGES="cmake mingw-w64 wine-stable"
+    - os: linux
+      env: >
+        BUILD_FLAVOR=ubuntu
+        BUILD_RELEASE=bionic
+        BUILD_ARCH=amd64
+        TOOLCHAIN=linux-mingw-w64-cxx17
+        BUILD_PACKAGES="cmake mingw-w64 wine-stable"
+
+before_install:
+  # use the Dockerfile.<distro>.template file for building the image with sed magic
+  - |
+    sed \
+    -e "s/@BUILD_FLAVOR@/${BUILD_FLAVOR}/g" \
+    -e "s/@BUILD_RELEASE@/${BUILD_RELEASE}/g" \
+    -e "s/@BUILD_ARCH@/${BUILD_ARCH}/g" \
+    -e "s/@BUILD_PACKAGES@/${BUILD_PACKAGES}/g" \
+    Dockerfile.$BUILD_FLAVOR.template | tee Dockerfile.$BUILD_FLAVOR.$BUILD_RELEASE.$BUILD_ARCH
+  - docker build -f Dockerfile.$BUILD_FLAVOR.$BUILD_RELEASE.$BUILD_ARCH -t glog-devel .
+
+script: |
+  # run the respective .travis.<distro>.sh script
+  docker run \
+  -e BUILD_FLAVOR="$BUILD_FLAVOR" \
+  -e BUILD_RELEASE="$BUILD_RELEASE" \
+  -e BUILD_ARCH="$BUILD_ARCH" \
+  -e PROJECT_DIR="$PROJECT_DIR" \
+  -e TOOLCHAIN="$TOOLCHAIN" \
+  -e RUN_TESTS="$RUN_TESTS" \
+  -it glog-devel ./.travis.$BUILD_FLAVOR.sh
+
diff --git a/third_party/google-glog/AUTHORS b/third_party/google-glog/AUTHORS
new file mode 100644
index 0000000..03238cb
--- /dev/null
+++ b/third_party/google-glog/AUTHORS
@@ -0,0 +1,24 @@
+# This is the official list of glog authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS files.
+# See the latter for an explanation.
+#
+# Names should be added to this file as:
+#	Name or Organization <email address>
+# The email address is not required for organizations.
+#
+# Please keep the list sorted.
+
+Abhishek Dasgupta <abhi2743@gmail.com>
+Abhishek Parmar <abhishek@orng.net>
+Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
+Andy Ying <andy@trailofbits.com>
+Brian Silverman <bsilver16384@gmail.com>
+Google Inc.
+Guillaume Dumont <dumont.guillaume@gmail.com>
+Michael Tanner <michael@tannertaxpro.com>
+MiniLight <MiniLightAR@Gmail.com>
+romange <romange@users.noreply.github.com>
+Sergiu Deitsch <sergiu.deitsch@gmail.com>
+tbennun <tbennun@gmail.com>
+Teddy Reed <teddy@prosauce.org>
+Zhongming Qu <qzmfranklin@gmail.com>
diff --git a/third_party/google-glog/BUILD b/third_party/google-glog/BUILD
new file mode 100644
index 0000000..37fb27b
--- /dev/null
+++ b/third_party/google-glog/BUILD
@@ -0,0 +1,5 @@
+licenses(['notice'])
+
+load(':bazel/glog.bzl', 'glog_library')
+
+glog_library()
diff --git a/third_party/google-glog/CMakeLists.txt b/third_party/google-glog/CMakeLists.txt
new file mode 100644
index 0000000..dca6850
--- /dev/null
+++ b/third_party/google-glog/CMakeLists.txt
@@ -0,0 +1,684 @@
+cmake_minimum_required (VERSION 3.0)
+
+if (POLICY CMP0042)
+  cmake_policy (SET CMP0042 NEW)
+endif (POLICY CMP0042)
+
+if (POLICY CMP0063)
+  cmake_policy (SET CMP0063 NEW)
+endif (POLICY CMP0063)
+
+project(glog VERSION 0.3.5 LANGUAGES C CXX)
+
+set (CPACK_PACKAGE_NAME glog)
+set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "")
+set (CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
+set (CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
+set (CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
+set (CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
+
+option (WITH_GFLAGS "Use gflags" ON)
+option (WITH_THREADS "Enable multithreading support" ON)
+option (WITH_TLS "Enable Thread Local Storage (TLS) support" ON)
+option (BUILD_SHARED_LIBS "Build shared libraries" OFF)
+option (PRINT_UNSYMBOLIZED_STACK_TRACES
+  "Print raw pc values on symbolization failure" OFF)
+
+list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+
+include (CheckCSourceCompiles)
+include (CheckCXXCompilerFlag)
+include (CheckCXXSourceCompiles)
+include (CheckCXXSourceRuns)
+include (CheckFunctionExists)
+include (CheckIncludeFile)
+include (CheckIncludeFileCXX)
+include (CheckLibraryExists)
+include (CheckStructHasMember)
+include (CheckSymbolExists)
+include (CheckTypeSize)
+include (CMakePackageConfigHelpers)
+include (CMakePushCheckState)
+include (CPack)
+include (CTest)
+include (DetermineGflagsNamespace)
+include (GNUInstallDirs)
+
+set (CMAKE_DEBUG_POSTFIX d)
+set (CMAKE_THREAD_PREFER_PTHREAD 1)
+
+if (WITH_GFLAGS)
+  find_package (gflags 2.2.0)
+
+  if (gflags_FOUND)
+    set (HAVE_LIB_GFLAGS 1)
+    determine_gflags_namespace (gflags_NAMESPACE)
+  endif (gflags_FOUND)
+endif (WITH_GFLAGS)
+
+if (WITH_THREADS)
+  find_package (Threads)
+endif (WITH_THREADS)
+
+check_include_file (dlfcn.h HAVE_DLFCN_H)
+check_include_file (execinfo.h HAVE_EXECINFO_H)
+check_include_file (glob.h HAVE_GLOB_H)
+check_include_file (inttypes.h HAVE_INTTYPES_H)
+check_include_file (libunwind.h HAVE_LIBUNWIND_H)
+check_include_file (memory.h HAVE_MEMORY_H)
+check_include_file (pwd.h HAVE_PWD_H)
+check_include_file (stdint.h HAVE_STDINT_H)
+check_include_file (stdlib.h HAVE_STDLIB_H)
+check_include_file (string.h HAVE_STRING_H)
+check_include_file (strings.h HAVE_STRINGS_H)
+check_include_file (sys/stat.h HAVE_SYS_STAT_H)
+check_include_file (sys/syscall.h HAVE_SYS_SYSCALL_H)
+check_include_file (sys/time.h HAVE_SYS_TIME_H)
+check_include_file (sys/types.h HAVE_SYS_TYPES_H)
+check_include_file (sys/utsname.h HAVE_SYS_UTSNAME_H)
+check_include_file (syscall.h HAVE_SYSCALL_H)
+check_include_file (syslog.h HAVE_SYSLOG_H)
+check_include_file (ucontext.h HAVE_UCONTEXT_H)
+check_include_file (unistd.h HAVE_UNISTD_H)
+check_include_file (unwind.h HAVE_UNWIND_H)
+check_include_file (pwd.h HAVE_PWD_H)
+
+check_include_file_cxx ("ext/hash_map" HAVE_EXT_HASH_MAP)
+check_include_file_cxx ("ext/hash_set" HAVE_EXT_HASH_SET)
+check_include_file_cxx ("ext/slist" HAVE_EXT_SLIST)
+check_include_file_cxx ("tr1/unordered_map" HAVE_TR1_UNORDERED_MAP)
+check_include_file_cxx ("tr1/unordered_set" HAVE_TR1_UNORDERED_SET)
+check_include_file_cxx ("unordered_map" HAVE_UNORDERED_MAP)
+check_include_file_cxx ("unordered_set" HAVE_UNORDERED_SET)
+
+check_type_size ("unsigned __int16" HAVE___UINT16)
+check_type_size (u_int16_t HAVE_U_INT16_T)
+check_type_size (uint16_t HAVE_UINT16_T)
+
+check_function_exists (dladdr HAVE_DLADDR)
+check_function_exists (fcntl HAVE_FCNTL)
+check_function_exists (pread HAVE_PREAD)
+check_function_exists (pwrite HAVE_PWRITE)
+check_function_exists (sigaction HAVE_SIGACTION)
+check_function_exists (sigaltstack HAVE_SIGALSTACK)
+
+# NOTE gcc does not fail if you pass a non-existent -Wno-* option as an
+# argument. However, it will happily fail if you pass the corresponding -W*
+# option. So, we check whether options that disable warnings exist by testing
+# the availability of the corresponding option that enables the warning. This
+# eliminates the need to check for compiler for several (mainly Clang) options.
+
+check_cxx_compiler_flag (-Wdeprecated HAVE_NO_DEPRECATED)
+check_cxx_compiler_flag (-Wunnamed-type-template-args
+    HAVE_NO_UNNAMED_TYPE_TEMPLATE_ARGS)
+
+# NOTE: Cannot use check_function_exists here since >=vc-14.0 can define
+# snprintf as an inline function
+check_symbol_exists (snprintf stdio.h HAVE_SNPRINTF)
+
+check_library_exists (unwind get_static_proc_name "" HAVE_LIB_UNWIND)
+check_library_exists (dbghelp UnDecorateSymbolName "" HAVE_DBGHELP)
+
+find_library (UNWIND_LIBRARY NAMES unwind DOC "unwind library")
+mark_as_advanced (UNWIND_LIBRARY)
+
+check_c_source_compiles ("
+#include <stdlib.h>
+static void foo(void) __attribute__ ((unused));
+int main(void) { return 0; }
+" HAVE___ATTRIBUTE__)
+
+check_c_source_compiles ("
+#include <stdlib.h>
+static void foo(void) __attribute__ ((visibility(\"default\")));
+int main(void) { return 0; }
+" HAVE___ATTRIBUTE__VISIBILITY_DEFAULT)
+
+check_c_source_compiles ("
+#include <stdlib.h>
+static void foo(void) __attribute__ ((visibility(\"hidden\")));
+int main(void) { return 0; }
+" HAVE___ATTRIBUTE__VISIBILITY_HIDDEN)
+
+check_c_source_compiles ("
+int main(void) { if (__builtin_expect(0, 0)) return 1; return 0; }
+" HAVE___BUILTIN_EXPECT)
+
+check_c_source_compiles ("
+int main(void)
+{
+  int a; if (__sync_val_compare_and_swap(&a, 0, 1)) return 1; return 0;
+}
+" HAVE___SYNC_VAL_COMPARE_AND_SWAP)
+
+check_c_source_compiles ("
+#define _XOPEN_SOURCE 500
+#include <pthread.h>
+int main(void)
+{
+  pthread_rwlock_t l;
+  pthread_rwlock_init(&l, NULL);
+  pthread_rwlock_rdlock(&l);
+  return 0;
+}
+" HAVE_RWLOCK)
+
+check_c_source_compiles ("
+__declspec(selectany) int a;
+int main(void) { return 0; }
+" HAVE___DECLSPEC)
+
+check_cxx_source_compiles ("
+#include <vector>
+vector<int> t; int main() { }
+" STL_NO_NAMESPACE)
+
+check_cxx_source_compiles ("
+#include <vector>
+std::vector<int> t; int main() { }
+" STL_STD_NAMESPACE)
+
+check_cxx_source_compiles ("
+#include <iostream>
+std::ostream& operator<<(std::ostream&, struct s);
+using ::operator<<;
+int main() { }
+" HAVE_USING_OPERATOR)
+
+check_cxx_source_compiles ("
+namespace Outer { namespace Inner { int i = 0; }}
+using namespace Outer::Inner;;
+int main() { return i; }
+" HAVE_NAMESPACES)
+
+check_cxx_source_compiles ("
+__thread int tls;
+int main() { }
+" HAVE_GCC_TLS)
+
+check_cxx_source_compiles ("
+__declspec(thread) int tls;
+int main() { }
+" HAVE_MSVC_TLS)
+
+check_cxx_source_compiles ("
+thread_local int tls;
+int main() { }
+" HAVE_CXX11_TLS)
+
+check_cxx_source_compiles ("
+#include <type_traits>
+std::aligned_storage<sizeof(char), alignof(char)>::type data;
+int main() { }
+" HAVE_ALIGNED_STORAGE)
+
+if (WITH_TLS)
+  # Cygwin does not support the thread attribute. Don't bother.
+  if (HAVE_GCC_TLS)
+    set (GLOG_THREAD_LOCAL_STORAGE "__thread")
+  elseif (HAVE_MSVC_TLS)
+    set (GLOG_THREAD_LOCAL_STORAGE "__declspec(thread)")
+  elseif (HAVE_CXX11_TLS)
+    set (GLOG_THREAD_LOCAL_STORAGE thread_local)
+  endif (HAVE_GCC_TLS)
+endif (WITH_TLS)
+
+set (_PC_FIELDS
+  "gregs[REG_PC]"
+  "gregs[REG_EIP]"
+  "gregs[REG_RIP]"
+  "sc_ip"
+  "uc_regs->gregs[PT_NIP]"
+  "gregs[R15]"
+  "arm_pc"
+  "mc_eip"
+  "mc_rip"
+  "__gregs[REG_EIP]"
+  "__gregs[REG_RIP]"
+  "ss.eip"
+  "__ss.__eip"
+  "ss.rip"
+  "__ss.__rip"
+  "ss.srr0"
+  "__ss.__srr0"
+)
+
+set (_PC_HEADERS ucontext.h signal.h)
+
+if (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
+  foreach (_PC_FIELD ${_PC_FIELDS})
+    foreach (_PC_HEADER ${_PC_HEADERS})
+      set (_TMP
+      ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/uctfield.c)
+      file (WRITE ${_TMP} "
+#define _GNU_SOURCE 1
+#include <${_PC_HEADER}>
+int main(void)
+{
+  ucontext_t u;
+  return u.${_PC_FIELD} == 0;
+}
+")
+      try_compile (HAVE_PC_FROM_UCONTEXT ${CMAKE_CURRENT_BINARY_DIR} ${_TMP}
+        COMPILE_DEFINITIONS _GNU_SOURCE=1)
+
+      if (HAVE_PC_FROM_UCONTEXT)
+        set (PC_FROM_UCONTEXT ${_PC_FIELD} CACHE)
+      endif (HAVE_PC_FROM_UCONTEXT)
+    endforeach (_PC_HEADER)
+  endforeach (_PC_FIELD)
+endif  (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
+
+if (STL_STD_NAMESPACE)
+  set (STL_NAMESPACE std)
+else (STL_STD_NAMESPACE)
+  set (STL_NAMESPACE "")
+endif (STL_STD_NAMESPACE)
+
+set (GOOGLE_NAMESPACE google)
+set (_START_GOOGLE_NAMESPACE_ "namespace ${GOOGLE_NAMESPACE} {")
+set (_END_GOOGLE_NAMESPACE_ "}")
+
+if (HAVE___UINT16)
+  set (ac_cv_have___uint16 1)
+else (HAVE___UINT16)
+  set (ac_cv_have___uint16 0)
+endif (HAVE___UINT16)
+
+if (HAVE_INTTYPES_H)
+  set (ac_cv_have_inttypes_h 1)
+else (HAVE_INTTYPES_H)
+  set (ac_cv_have_inttypes_h 0)
+endif (HAVE_INTTYPES_H)
+
+if (HAVE_LIB_GFLAGS)
+  set (ac_cv_have_libgflags 1)
+else (HAVE_LIB_GFLAGS)
+  set (ac_cv_have_libgflags 0)
+endif (HAVE_LIB_GFLAGS)
+
+if (HAVE_STDINT_H)
+  set (ac_cv_have_stdint_h 1)
+else (HAVE_STDINT_H)
+  set (ac_cv_have_stdint_h 0)
+endif (HAVE_STDINT_H)
+
+if (HAVE_SYS_TYPES_H)
+  set (ac_cv_have_systypes_h 1)
+else (HAVE_SYS_TYPES_H)
+  set (ac_cv_have_systypes_h 0)
+endif (HAVE_SYS_TYPES_H)
+
+if (HAVE_U_INT16_T)
+  set (ac_cv_have_u_int16_t 1)
+else (HAVE_U_INT16_T)
+  set (ac_cv_have_u_int16_t 0)
+endif (HAVE_U_INT16_T)
+
+if (HAVE_UINT16_T)
+  set (ac_cv_have_uint16_t 1)
+else (HAVE_UINT16_T)
+  set (ac_cv_have_uint16_t 0)
+endif (HAVE_UINT16_T)
+
+if (HAVE_UNISTD_H)
+  set (ac_cv_have_unistd_h 1)
+else (HAVE_UNISTD_H)
+  set (ac_cv_have_unistd_h 0)
+endif (HAVE_UNISTD_H)
+
+set (ac_google_namespace ${GOOGLE_NAMESPACE})
+set (ac_google_end_namespace ${_END_GOOGLE_NAMESPACE_})
+set (ac_google_start_namespace ${_START_GOOGLE_NAMESPACE_})
+
+if (HAVE___ATTRIBUTE__)
+  set (ac_cv___attribute___noreturn "__attribute__((noreturn))")
+  set (ac_cv___attribute___noinline "__attribute__((noinline))")
+elseif (HAVE___DECLSPEC)
+  set (ac_cv___attribute___noreturn "__declspec(noreturn)")
+  #set (ac_cv___attribute___noinline "__declspec(noinline)")
+endif (HAVE___ATTRIBUTE__)
+
+if (HAVE___BUILTIN_EXPECT)
+  set (ac_cv_have___builtin_expect 1)
+else (HAVE___BUILTIN_EXPECT)
+  set (ac_cv_have___builtin_expect 0)
+endif (HAVE___BUILTIN_EXPECT)
+
+if (HAVE_USING_OPERATOR)
+  set (ac_cv_cxx_using_operator 1)
+else (HAVE_USING_OPERATOR)
+  set (ac_cv_cxx_using_operator 0)
+endif (HAVE_USING_OPERATOR)
+
+if (HAVE_EXECINFO_H)
+  set (HAVE_STACKTRACE 1)
+endif (HAVE_EXECINFO_H)
+
+if (WIN32 OR CYGWIN)
+  cmake_push_check_state (RESET)
+  set (CMAKE_REQUIRED_LIBRARIES DbgHelp)
+
+  check_cxx_source_runs ([=[
+  #include <windows.h>
+  #include <dbghelp.h>
+  #include <cstdlib>
+
+  void foobar() { }
+
+  int main()
+  {
+      HANDLE process = GetCurrentProcess();
+
+      if (!SymInitialize(process, NULL, TRUE))
+          return EXIT_FAILURE;
+
+      char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
+      SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(buf);
+      symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+      symbol->MaxNameLen = MAX_SYM_NAME;
+
+      void* const pc = reinterpret_cast<void*>(&foobar);
+      BOOL ret = SymFromAddr(process, reinterpret_cast<DWORD64>(pc), 0, symbol);
+
+      return ret ? EXIT_SUCCESS : EXIT_FAILURE;
+  }
+  ]=] HAVE_SYMBOLIZE)
+
+  cmake_pop_check_state ()
+
+  if (HAVE_SYMBOLIZE)
+    set (HAVE_STACKTRACE 1)
+  endif (HAVE_SYMBOLIZE)
+elseif (UNIX OR (APPLE AND HAVE_DLADDR))
+  set (HAVE_SYMBOLIZE 1)
+endif (WIN32 OR CYGWIN)
+
+check_cxx_source_compiles ("
+#include <cstdlib>
+#include <time.h>
+int main()
+{
+    time_t timep;
+    struct tm result;
+    localtime_r(&timep, &result);
+    return EXIT_SUCCESS;
+}
+" HAVE_LOCALTIME_R)
+
+set (SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
+
+if (WITH_THREADS AND Threads_FOUND)
+  if (CMAKE_USE_PTHREADS_INIT)
+    set (HAVE_PTHREAD 1)
+  endif (CMAKE_USE_PTHREADS_INIT)
+else (WITH_THREADS AND Threads_FOUND)
+  set (NO_THREADS 1)
+endif (WITH_THREADS AND Threads_FOUND)
+
+set (TEST_SRC_DIR \"${CMAKE_CURRENT_SOURCE_DIR}\")
+
+configure_file (src/config.h.cmake.in config.h)
+configure_file (src/glog/logging.h.in glog/logging.h @ONLY)
+configure_file (src/glog/raw_logging.h.in glog/raw_logging.h @ONLY)
+configure_file (src/glog/stl_logging.h.in glog/stl_logging.h @ONLY)
+configure_file (src/glog/vlog_is_on.h.in glog/vlog_is_on.h @ONLY)
+
+set (CMAKE_CXX_VISIBILITY_PRESET default)
+set (CMAKE_VISIBILITY_INLINES_HIDDEN 1)
+
+set (GLOG_PUBLIC_H
+  ${CMAKE_CURRENT_BINARY_DIR}/glog/logging.h
+  ${CMAKE_CURRENT_BINARY_DIR}/glog/raw_logging.h
+  ${CMAKE_CURRENT_BINARY_DIR}/glog/stl_logging.h
+  ${CMAKE_CURRENT_BINARY_DIR}/glog/vlog_is_on.h
+  src/glog/log_severity.h
+)
+
+set (GLOG_SRCS
+  ${GLOG_PUBLIC_H}
+  src/base/commandlineflags.h
+  src/base/googleinit.h
+  src/base/mutex.h
+  src/demangle.cc
+  src/demangle.h
+  src/logging.cc
+  src/raw_logging.cc
+  src/symbolize.cc
+  src/symbolize.h
+  src/utilities.cc
+  src/utilities.h
+  src/vlog_is_on.cc
+)
+
+if (HAVE_PTHREAD OR WIN32)
+  list (APPEND GLOG_SRCS src/signalhandler.cc)
+endif (HAVE_PTHREAD OR WIN32)
+
+if (WIN32)
+  list (APPEND GLOG_SRCS
+    src/windows/port.cc
+    src/windows/port.h
+  )
+endif (WIN32)
+
+add_compile_options ($<$<AND:$<BOOL:${HAVE_NO_UNNAMED_TYPE_TEMPLATE_ARGS}>,$<NOT:$<CXX_COMPILER_ID:GNU>>>:-Wno-unnamed-type-template-args>)
+
+add_library (glog
+  ${GLOG_SRCS}
+)
+add_library(glog::glog ALIAS glog)
+
+set_target_properties (glog PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+if (UNWIND_LIBRARY)
+  target_link_libraries (glog PUBLIC ${UNWIND_LIBRARY})
+endif (UNWIND_LIBRARY)
+
+if (HAVE_DBGHELP)
+   target_link_libraries (glog PUBLIC dbghelp)
+endif (HAVE_DBGHELP)
+
+if (HAVE_PTHREAD)
+  target_link_libraries (glog PUBLIC ${CMAKE_THREAD_LIBS_INIT})
+endif (HAVE_PTHREAD)
+
+if (WIN32 AND HAVE_SNPRINTF)
+  set_property (SOURCE src/windows/port.cc APPEND PROPERTY COMPILE_DEFINITIONS
+    HAVE_SNPRINTF)
+endif (WIN32 AND HAVE_SNPRINTF)
+
+if (gflags_FOUND)
+  target_link_libraries (glog PUBLIC gflags)
+
+  if (NOT BUILD_SHARED_LIBS)
+    # Don't use __declspec(dllexport|dllimport) if this is a static build
+    targeT_compile_definitions (glog PUBLIC GFLAGS_DLL_DECLARE_FLAG= GFLAGS_DLL_DEFINE_FLAG=)
+  endif (NOT BUILD_SHARED_LIBS)
+endif (gflags_FOUND)
+
+set_target_properties (glog PROPERTIES VERSION ${PROJECT_VERSION})
+set_target_properties (glog PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR})
+
+if (WIN32)
+  target_compile_definitions (glog PUBLIC GLOG_NO_ABBREVIATED_SEVERITIES)
+endif (WIN32)
+
+set_target_properties (glog PROPERTIES PUBLIC_HEADER "${GLOG_PUBLIC_H}")
+
+set (_glog_CMake_BINDIR ${CMAKE_INSTALL_BINDIR})
+set (_glog_CMake_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR})
+set (_glog_CMake_LIBDIR ${CMAKE_INSTALL_LIBDIR})
+set (_glog_CMake_INSTALLDIR ${_glog_CMake_LIBDIR}/cmake/glog)
+
+target_include_directories (glog BEFORE PUBLIC
+  "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>"
+  "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
+  "$<INSTALL_INTERFACE:${_glog_CMake_INCLUDE_DIR}>"
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
+
+if (WIN32)
+  target_include_directories (glog PUBLIC
+    "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/windows>"
+    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/windows)
+endif (WIN32)
+
+set_target_properties (glog PROPERTIES DEFINE_SYMBOL LIBGLOG_EXPORTS)
+
+if (NOT BUILD_SHARED_LIBS)
+  target_compile_definitions (glog PUBLIC GOOGLE_GLOG_DLL_DECL=)
+else (NOT BUILD_SHARED_LIBS)
+  target_compile_definitions (glog PRIVATE GOOGLE_GLOG_IS_A_DLL=1)
+
+  if (HAVE___ATTRIBUTE__VISIBILITY_DEFAULT)
+    set (_EXPORT "__attribute__((visibility(\"default\")))")
+    set (_IMPORT "")
+  elseif (HAVE___DECLSPEC)
+    set (_EXPORT "__declspec(dllexport)")
+    set (_IMPORT "__declspec(dllimport)")
+  endif (HAVE___ATTRIBUTE__VISIBILITY_DEFAULT)
+
+  target_compile_definitions (glog PRIVATE
+    "GOOGLE_GLOG_DLL_DECL=${_EXPORT}")
+  target_compile_definitions (glog INTERFACE
+    "GOOGLE_GLOG_DLL_DECL=${_IMPORT}")
+  target_compile_definitions (glog INTERFACE
+    "GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS=${_IMPORT}")
+endif (NOT BUILD_SHARED_LIBS)
+
+# Unit testing
+
+if (BUILD_TESTING)
+  add_executable (logging_unittest
+    src/logging_unittest.cc
+  )
+
+  target_link_libraries (logging_unittest PRIVATE glog)
+
+  add_executable (stl_logging_unittest
+    src/stl_logging_unittest.cc
+  )
+
+  target_link_libraries (stl_logging_unittest PRIVATE glog)
+
+  if (HAVE_NO_DEPRECATED)
+    set_property (TARGET stl_logging_unittest APPEND PROPERTY COMPILE_OPTIONS
+      -Wno-deprecated)
+  endif (HAVE_NO_DEPRECATED)
+
+  if (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
+    target_compile_definitions (stl_logging_unittest PRIVATE
+      GLOG_STL_LOGGING_FOR_UNORDERED)
+  endif (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
+
+  if (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
+    target_compile_definitions (stl_logging_unittest PRIVATE
+      GLOG_STL_LOGGING_FOR_TR1_UNORDERED)
+  endif (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
+
+  if (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
+    target_compile_definitions (stl_logging_unittest PRIVATE
+      GLOG_STL_LOGGING_FOR_EXT_HASH)
+  endif (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
+
+  if (HAVE_EXT_SLIST)
+    target_compile_definitions (stl_logging_unittest PRIVATE
+      GLOG_STL_LOGGING_FOR_EXT_SLIST)
+  endif (HAVE_EXT_SLIST)
+
+  if (HAVE_SYMBOLIZE)
+    add_executable (symbolize_unittest
+      src/symbolize_unittest.cc
+    )
+
+    target_link_libraries (symbolize_unittest PRIVATE glog)
+  endif (HAVE_SYMBOLIZE)
+
+  add_executable (demangle_unittest
+    src/demangle_unittest.cc
+  )
+
+  target_link_libraries (demangle_unittest PRIVATE glog)
+
+  if (HAVE_STACKTRACE)
+    add_executable (stacktrace_unittest
+      src/stacktrace_unittest.cc
+    )
+
+    target_link_libraries (stacktrace_unittest PRIVATE glog)
+  endif (HAVE_STACKTRACE)
+
+  add_executable (utilities_unittest
+    src/utilities_unittest.cc
+  )
+
+  target_link_libraries (utilities_unittest PRIVATE glog)
+
+  if (HAVE_STACKTRACE AND HAVE_SYMBOLIZE)
+    add_executable (signalhandler_unittest
+      src/signalhandler_unittest.cc
+    )
+
+    target_link_libraries (signalhandler_unittest PRIVATE glog)
+  endif (HAVE_STACKTRACE AND HAVE_SYMBOLIZE)
+
+  add_test (NAME demangle COMMAND demangle_unittest)
+  add_test (NAME logging COMMAND logging_unittest)
+
+  if (TARGET signalhandler_unittest)
+    add_test (NAME signalhandler COMMAND signalhandler_unittest)
+  endif (TARGET signalhandler_unittest)
+
+  if (TARGET stacktrace_unittest)
+    add_test (NAME stacktrace COMMAND stacktrace_unittest)
+    set_tests_properties(stacktrace PROPERTIES TIMEOUT 30)
+  endif (TARGET stacktrace_unittest)
+
+  add_test (NAME stl_logging COMMAND stl_logging_unittest)
+
+  if (TARGET symbolize_unittest)
+    add_test (NAME symbolize COMMAND symbolize_unittest)
+  endif (TARGET symbolize_unittest)
+endif (BUILD_TESTING)
+
+install (TARGETS glog
+  EXPORT glog-targets
+  RUNTIME DESTINATION ${_glog_CMake_BINDIR}
+  PUBLIC_HEADER DESTINATION ${_glog_CMake_INCLUDE_DIR}/glog
+  LIBRARY DESTINATION ${_glog_CMake_LIBDIR}
+  ARCHIVE DESTINATION ${_glog_CMake_LIBDIR})
+
+set (glog_CMake_VERSION 3.0)
+
+if (gflags_FOUND)
+  # Ensure clients locate only the package config and not third party find
+  # modules having the same name. This avoid cmake_policy PUSH/POP errors.
+  if (CMAKE_VERSION VERSION_LESS 3.9)
+    set (gflags_DEPENDENCY "find_dependency (gflags ${gflags_VERSION})")
+  else (CMAKE_VERSION VERSION_LESS 3.9)
+    # Passing additional find_package arguments to find_dependency is possible
+    # starting with CMake 3.9.
+    set (glog_CMake_VERSION 3.9)
+    set (gflags_DEPENDENCY "find_dependency (gflags ${gflags_VERSION} NO_MODULE)")
+  endif (CMAKE_VERSION VERSION_LESS 3.9)
+endif (gflags_FOUND)
+
+configure_package_config_file (glog-config.cmake.in
+  ${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake
+  INSTALL_DESTINATION ${_glog_CMake_INSTALLDIR}
+  NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+
+write_basic_package_version_file (glog-config-version.cmake VERSION
+  ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion)
+
+export (TARGETS glog NAMESPACE glog:: FILE glog-targets.cmake)
+export (PACKAGE glog)
+
+install (FILES
+  ${CMAKE_CURRENT_BINARY_DIR}/glog-config.cmake
+  ${CMAKE_CURRENT_BINARY_DIR}/glog-config-version.cmake
+  DESTINATION ${_glog_CMake_INSTALLDIR})
+
+install (EXPORT glog-targets NAMESPACE glog:: DESTINATION
+  ${_glog_CMake_INSTALLDIR})
diff --git a/third_party/google-glog/CONTRIBUTING.md b/third_party/google-glog/CONTRIBUTING.md
new file mode 100644
index 0000000..43de4c9
--- /dev/null
+++ b/third_party/google-glog/CONTRIBUTING.md
@@ -0,0 +1,58 @@
+# How to contribute #
+
+We'd love to accept your patches and contributions to this project.  There are
+a just a few small guidelines you need to follow.
+
+
+## Contributor License Agreement ##
+
+Contributions to any Google project must be accompanied by a Contributor
+License Agreement.  This is not a copyright **assignment**, it simply gives
+Google permission to use and redistribute your contributions as part of the
+project.
+
+  * If you are an individual writing original source code and you're sure you
+    own the intellectual property, then you'll need to sign an [individual
+    CLA][].
+
+  * If you work for a company that wants to allow you to contribute your work,
+    then you'll need to sign a [corporate CLA][].
+
+You generally only need to submit a CLA once, so if you've already submitted
+one (even if it was for a different project), you probably don't need to do it
+again.
+
+[individual CLA]: https://developers.google.com/open-source/cla/individual
+[corporate CLA]: https://developers.google.com/open-source/cla/corporate
+
+Once your CLA is submitted (or if you already submitted one for
+another Google project), make a commit adding yourself to the
+[AUTHORS][] and [CONTRIBUTORS][] files. This commit can be part
+of your first [pull request][].
+
+[AUTHORS]: AUTHORS
+[CONTRIBUTORS]: CONTRIBUTORS
+
+
+## Submitting a patch ##
+
+  1. It's generally best to start by opening a new issue describing the bug or
+     feature you're intending to fix.  Even if you think it's relatively minor,
+     it's helpful to know what people are working on.  Mention in the initial
+     issue that you are planning to work on that bug or feature so that it can
+     be assigned to you.
+
+  1. Follow the normal process of [forking][] the project, and setup a new
+     branch to work in.  It's important that each group of changes be done in
+     separate branches in order to ensure that a pull request only includes the
+     commits related to that bug or feature.
+
+  1. Do your best to have [well-formed commit messages][] for each change.
+     This provides consistency throughout the project, and ensures that commit
+     messages are able to be formatted properly by various git tools.
+
+  1. Finally, push the commits to your fork and submit a [pull request][].
+
+[forking]: https://help.github.com/articles/fork-a-repo
+[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+[pull request]: https://help.github.com/articles/creating-a-pull-request
diff --git a/third_party/google-glog/CONTRIBUTORS b/third_party/google-glog/CONTRIBUTORS
new file mode 100644
index 0000000..432e91b
--- /dev/null
+++ b/third_party/google-glog/CONTRIBUTORS
@@ -0,0 +1,44 @@
+# People who have agreed to one of the CLAs and can contribute patches.
+# The AUTHORS file lists the copyright holders; this file
+# lists people.  For example, Google employees are listed here
+# but not in AUTHORS, because Google holds the copyright.
+#
+# Names should be added to this file only after verifying that
+# the individual or the individual's organization has agreed to
+# the appropriate Contributor License Agreement, found here:
+#
+# https://developers.google.com/open-source/cla/individual
+# https://developers.google.com/open-source/cla/corporate
+#
+# The agreement for individuals can be filled out on the web.
+#
+# When adding J Random Contributor's name to this file,
+# either J's name or J's organization's name should be
+# added to the AUTHORS file, depending on whether the
+# individual or corporate CLA was used.
+#
+# Names should be added to this file as:
+#     Name <email address>
+#
+# Please keep the list sorted.
+
+Abhishek Dasgupta <abhi2743@gmail.com>
+Abhishek Parmar <abhishek@orng.net>
+Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
+Andy Ying <andy@trailofbits.com>
+Brian Silverman <bsilver16384@gmail.com>
+Fumitoshi Ukai <ukai@google.com>
+Guillaume Dumont <dumont.guillaume@gmail.com>
+Håkan L. S. Younes <hyounes@google.com>
+Ivan Penkov <ivanpe@google.com>
+Jim Ray <jimray@google.com>
+Michael Tanner <michael@tannertaxpro.com>
+MiniLight <MiniLightAR@Gmail.com>
+Peter Collingbourne <pcc@google.com>
+Rodrigo Queiro <rodrigoq@google.com>
+romange <romange@users.noreply.github.com>
+Sergiu Deitsch <sergiu.deitsch@gmail.com>
+Shinichiro Hamaji <hamaji@google.com>
+tbennun <tbennun@gmail.com>
+Teddy Reed <teddy@prosauce.org>
+Zhongming Qu <qzmfranklin@gmail.com>
diff --git a/third_party/google-glog/COPYING b/third_party/google-glog/COPYING
new file mode 100644
index 0000000..38396b5
--- /dev/null
+++ b/third_party/google-glog/COPYING
@@ -0,0 +1,65 @@
+Copyright (c) 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+A function gettimeofday in utilities.cc is based on
+
+http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/COPYING&q=GetSystemTimeAsFileTime%20license:bsd
+
+The license of this code is:
+
+Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and contributors
+All Rights Reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name(s) of the above-listed copyright holder(s) nor the
+   names of its contributors may be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/google-glog/ChangeLog b/third_party/google-glog/ChangeLog
new file mode 100644
index 0000000..d1b4248
--- /dev/null
+++ b/third_party/google-glog/ChangeLog
@@ -0,0 +1,84 @@
+2013-02-01  Google Inc. <opensource@google.com>
+
+	* google-glog: version 0.3.3
+	* Add --disable-rtti option for configure.
+	* Visual Studio build and test fix.
+	* QNX build fix (thanks vanuan).
+	* Reduce warnings.
+	* Fixed LOG_SYSRESULT (thanks ukai).
+	* FreeBSD build fix (thanks yyanagisawa).
+	* Clang build fix.
+	* Now users can re-initialize glog after ShutdownGoogleLogging.
+	* Color output support by GLOG_colorlogtostderr (thanks alexs).
+	* Now glog's ABI around flags are compatible with gflags.
+	* Document mentions how to modify flags from user programs.
+
+2012-01-12  Google Inc. <opensource@google.com>
+
+	* google-glog: version 0.3.2
+	* Clang support.
+	* Demangler and stacktrace improvement for newer GCCs.
+	* Now fork(2) doesn't mess up log files.
+	* Make valgrind happier.
+	* Reduce warnings for more -W options.
+	* Provide a workaround for ERROR defined by windows.h.
+
+2010-06-15  Google Inc. <opensource@google.com>
+
+	* google-glog: version 0.3.1
+	* GLOG_* environment variables now work even when gflags is installed.
+	* Snow leopard support.
+	* Now we can build and test from out side tree.
+	* Add DCHECK_NOTNULL.
+	* Add ShutdownGoogleLogging to close syslog (thanks DGunchev)
+	* Fix --enable-frame-pointers option (thanks kazuki.ohta)
+	* Fix libunwind detection (thanks giantchen)
+
+2009-07-30  Google Inc. <opensource@google.com>
+
+	* google-glog: version 0.3.0
+	* Fix a deadlock happened when user uses glog with recent gflags.
+	* Suppress several unnecessary warnings (thanks keir).
+	* NetBSD and OpenBSD support.
+	* Use Win32API GetComputeNameA properly (thanks magila).
+	* Fix user name detection for Windows (thanks ademin).
+	* Fix several minor bugs.
+
+2009-04-10  Google Inc. <opensource@google.com>
+	* google-glog: version 0.2.1
+	* Fix timestamps of VC++ version.
+	* Add pkg-config support (thanks Tomasz)
+	* Fix build problem when building with gtest (thanks Michael)
+	* Add --with-gflags option for configure (thanks Michael)
+	* Fixes for GCC 4.4 (thanks John)
+
+2009-01-23  Google Inc. <opensource@google.com>
+	* google-glog: version 0.2
+	* Add initial Windows VC++ support.
+	* Google testing/mocking frameworks integration.
+	* Link pthread library automatically.
+	* Flush logs in signal handlers.
+	* Add macros LOG_TO_STRING, LOG_AT_LEVEL, DVLOG, and LOG_TO_SINK_ONLY.
+	* Log microseconds.
+	* Add --log_backtrace_at option.
+	* Fix some minor bugs.
+
+2008-11-18  Google Inc. <opensource@google.com>
+	* google-glog: version 0.1.2
+	* Add InstallFailureSignalHandler(). (satorux)
+	* Re-organize the way to produce stacktraces.
+	* Don't define unnecessary macro DISALLOW_EVIL_CONSTRUCTORS.
+
+2008-10-15  Google Inc. <opensource@google.com>
+	* google-glog: version 0.1.1
+	* Support symbolize for MacOSX 10.5.
+	* BUG FIX: --vmodule didn't work with gflags.
+	* BUG FIX: symbolize_unittest failed with GCC 4.3.
+	* Several fixes on the document.
+
+2008-10-07  Google Inc. <opensource@google.com>
+
+	* google-glog: initial release:
+	The glog package contains a library that implements application-level
+	logging.  This library provides logging APIs based on C++-style
+	streams and various helper macros.
diff --git a/third_party/google-glog/Dockerfile.ubuntu.template b/third_party/google-glog/Dockerfile.ubuntu.template
new file mode 100644
index 0000000..14f9b95
--- /dev/null
+++ b/third_party/google-glog/Dockerfile.ubuntu.template
@@ -0,0 +1,14 @@
+# Build Ubuntu image
+FROM @BUILD_ARCH@/@BUILD_FLAVOR@:@BUILD_RELEASE@
+
+# see https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#/run
+RUN apt-get update && \
+  apt-get install -y --no-install-recommends \
+  @BUILD_PACKAGES@ \
+  build-essential \
+  g++
+
+RUN mkdir -p /usr/src/app
+WORKDIR /usr/src/app
+
+COPY . /usr/src/app
diff --git a/third_party/google-glog/INSTALL b/third_party/google-glog/INSTALL
new file mode 100644
index 0000000..0f3b55d
--- /dev/null
+++ b/third_party/google-glog/INSTALL
@@ -0,0 +1,297 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Glog-Specific Install Notes
+================================
+
+*** NOTE FOR 64-BIT LINUX SYSTEMS
+
+The glibc built-in stack-unwinder on 64-bit systems has some problems
+with the glog libraries.  (In particular, if you are using
+InstallFailureSignalHandler(), the signal may be raised in the middle
+of malloc, holding some malloc-related locks when they invoke the
+stack unwinder.  The built-in stack unwinder may call malloc
+recursively, which may require the thread to acquire a lock it already
+holds: deadlock.)
+
+For that reason, if you use a 64-bit system and you need
+InstallFailureSignalHandler(), we strongly recommend you install
+libunwind before trying to configure or install google glog.
+libunwind can be found at
+
+   http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz
+
+Even if you already have libunwind installed, you will probably still
+need to install from the snapshot to get the latest version.
+
+CAUTION: if you install libunwind from the URL above, be aware that
+you may have trouble if you try to statically link your binary with
+glog: that is, if you link with 'gcc -static -lgcc_eh ...'.  This
+is because both libunwind and libgcc implement the same C++ exception
+handling APIs, but they implement them differently on some platforms.
+This is not likely to be a problem on ia64, but may be on x86-64.
+
+Also, if you link binaries statically, make sure that you add
+-Wl,--eh-frame-hdr to your linker options. This is required so that
+libunwind can find the information generated by the compiler required
+for stack unwinding.
+
+Using -static is rare, though, so unless you know this will affect you
+it probably won't.
+
+If you cannot or do not wish to install libunwind, you can still try
+to use two kinds of stack-unwinder: 1. glibc built-in stack-unwinder
+and 2. frame pointer based stack-unwinder.
+
+1. As we already mentioned, glibc's unwinder has a deadlock issue.
+However, if you don't use InstallFailureSignalHandler() or you don't
+worry about the rare possibilities of deadlocks, you can use this
+stack-unwinder.  If you specify no options and libunwind isn't
+detected on your system, the configure script chooses this unwinder by
+default.
+
+2. The frame pointer based stack unwinder requires that your
+application, the glog library, and system libraries like libc, all be
+compiled with a frame pointer.  This is *not* the default for x86-64.
+
+If you are on x86-64 system, know that you have a set of system
+libraries with frame-pointers enabled, and compile all your
+applications with -fno-omit-frame-pointer, then you can enable the
+frame pointer based stack unwinder by passing the
+--enable-frame-pointers flag to configure.
+
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README.md' file for
+instructions specific to this package.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README.md' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  6. Often, you can also type `make uninstall' to remove the installed
+     files again.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README.md' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/third_party/google-glog/Makefile.am b/third_party/google-glog/Makefile.am
new file mode 100644
index 0000000..e750157
--- /dev/null
+++ b/third_party/google-glog/Makefile.am
@@ -0,0 +1,260 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = subdir-objects foreign
+
+# Make sure that when we re-make ./configure, we get the macros we need
+ACLOCAL_AMFLAGS = -I m4
+
+# This is so we can #include <glog/foo>
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+# This is mostly based on configure options
+AM_CXXFLAGS =
+
+# These are good warnings to turn on by default
+if GCC
+  AM_CXXFLAGS += -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+endif
+
+# These are x86-specific, having to do with frame-pointers
+if X86_64
+if ENABLE_FRAME_POINTERS
+  AM_CXXFLAGS += -fno-omit-frame-pointer
+else
+  # TODO(csilvers): check if -fomit-frame-pointer might be in $(CXXFLAGS),
+  #                 before setting this.
+  AM_CXXFLAGS += -DNO_FRAME_POINTER
+endif
+endif
+
+if DISABLE_RTTI
+  AM_CXXFLAGS += -fno-rtti
+endif
+
+glogincludedir = $(includedir)/glog
+## The .h files you want to install (that is, .h files that people
+## who install this package can include in their own applications.)
+## We have to include both the .h and .h.in forms.  The latter we
+## put in noinst_HEADERS.
+gloginclude_HEADERS = src/glog/log_severity.h
+nodist_gloginclude_HEADERS = src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h
+noinst_HEADERS = src/glog/logging.h.in src/glog/raw_logging.h.in src/glog/vlog_is_on.h.in src/glog/stl_logging.h.in
+
+docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
+## This is for HTML and other documentation you want to install.
+## Add your documentation files (in doc/) in addition to these
+## top-level boilerplate files.  Also add a TODO file if you have one.
+dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL README.md README.windows \
+                doc/designstyle.css doc/glog.html
+
+## The libraries (.so's) you want to install
+lib_LTLIBRARIES =
+
+# The libraries libglog depends on.
+COMMON_LIBS = $(PTHREAD_LIBS) $(GFLAGS_LIBS) $(UNWIND_LIBS)
+# Compile switches for our unittest.
+TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS) $(GFLAGS_CFLAGS) \
+              $(MINGW_CFLAGS) $(AM_CXXFLAGS)
+# Libraries for our unittest.
+TEST_LIBS = $(GTEST_LIBS) $(GMOCK_LIBS) $(GFLAGS_LIBS)
+
+## unittests you want to run when people type 'make check'.
+## TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
+## TESTS_ENVIRONMENT sets environment variables for when you run unittest,
+## but it only seems to take effect for *binary* unittests (argh!)
+TESTS =
+# Set a small stack size so that (at least on Linux) PIEs are mapped at a lower
+# address than DSOs. This is used by symbolize_pie_unittest to check that we can
+# successfully symbolize PIEs loaded at low addresses.
+TESTS_ENVIRONMENT = ulimit -s 8192;
+check_SCRIPTS =
+# Every time you add a unittest to check_SCRIPTS, add it here too
+noinst_SCRIPTS =
+# Binaries used for script-based unittests.
+TEST_BINARIES =
+
+TESTS += logging_unittest
+logging_unittest_SOURCES = $(gloginclude_HEADERS) \
+                           src/logging_unittest.cc \
+                           src/config_for_unittests.h \
+                           src/mock-log.h
+nodist_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+logging_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+check_SCRIPTS += logging_striplog_test_sh
+noinst_SCRIPTS += src/logging_striplog_test.sh
+logging_striplog_test_sh: logging_striptest0 logging_striptest2 logging_striptest10
+	$(top_srcdir)/src/logging_striplog_test.sh
+
+check_SCRIPTS += demangle_unittest_sh
+noinst_SCRIPTS += src/demangle_unittest.sh
+demangle_unittest_sh: demangle_unittest
+	$(builddir)/demangle_unittest  # force to create lt-demangle_unittest
+	$(top_srcdir)/src/demangle_unittest.sh
+
+check_SCRIPTS += signalhandler_unittest_sh
+noinst_SCRIPTS += src/signalhandler_unittest.sh
+signalhandler_unittest_sh: signalhandler_unittest
+	$(builddir)/signalhandler_unittest  # force to create lt-signalhandler_unittest
+	$(top_srcdir)/src/signalhandler_unittest.sh
+
+TEST_BINARIES += logging_striptest0
+logging_striptest0_SOURCES = $(gloginclude_HEADERS) \
+                             src/logging_striptest_main.cc
+nodist_logging_striptest0_SOURCES = $(nodist_gloginclude_HEADERS)
+logging_striptest0_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+logging_striptest0_LDFLAGS = $(PTHREAD_CFLAGS)
+logging_striptest0_LDADD = libglog.la $(COMMON_LIBS)
+
+TEST_BINARIES += logging_striptest2
+logging_striptest2_SOURCES = $(gloginclude_HEADERS) \
+                             src/logging_striptest2.cc
+nodist_logging_striptest2_SOURCES = $(nodist_gloginclude_HEADERS)
+logging_striptest2_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+logging_striptest2_LDFLAGS = $(PTHREAD_CFLAGS)
+logging_striptest2_LDADD = libglog.la $(COMMON_LIBS)
+
+TEST_BINARIES += logging_striptest10
+logging_striptest10_SOURCES = $(gloginclude_HEADERS) \
+                              src/logging_striptest10.cc
+nodist_logging_striptest10_SOURCES = $(nodist_gloginclude_HEADERS)
+logging_striptest10_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+logging_striptest10_LDFLAGS = $(PTHREAD_CFLAGS)
+logging_striptest10_LDADD = libglog.la $(COMMON_LIBS)
+
+TESTS += demangle_unittest
+demangle_unittest_SOURCES = $(gloginclude_HEADERS) \
+                            src/demangle_unittest.cc
+nodist_demangle_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+demangle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+demangle_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+demangle_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TESTS += stacktrace_unittest
+stacktrace_unittest_SOURCES = $(gloginclude_HEADERS) \
+                              src/stacktrace_unittest.cc
+nodist_stacktrace_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+stacktrace_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+stacktrace_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+stacktrace_unittest_LDADD = libglog.la $(COMMON_LIBS)
+
+TESTS += symbolize_unittest
+symbolize_unittest_SOURCES = $(gloginclude_HEADERS) \
+                              src/symbolize_unittest.cc
+nodist_symbolize_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+symbolize_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+symbolize_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+symbolize_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TESTS += symbolize_pie_unittest
+symbolize_pie_unittest_SOURCES = $(gloginclude_HEADERS) \
+                                 src/symbolize_unittest.cc
+nodist_symbolize_pie_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+symbolize_pie_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS) -fPIE
+symbolize_pie_unittest_LDFLAGS = $(PTHREAD_CFLAGS) -pie
+symbolize_pie_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TESTS += stl_logging_unittest
+stl_logging_unittest_SOURCES = $(gloginclude_HEADERS) \
+                               src/stl_logging_unittest.cc
+nodist_stl_logging_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+stl_logging_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+stl_logging_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+stl_logging_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TEST_BINARIES += signalhandler_unittest
+signalhandler_unittest_SOURCES = $(gloginclude_HEADERS) \
+                               src/signalhandler_unittest.cc
+nodist_signalhandler_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+signalhandler_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+signalhandler_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+signalhandler_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+TESTS += utilities_unittest
+utilities_unittest_SOURCES = $(gloginclude_HEADERS) \
+                             src/utilities_unittest.cc
+nodist_utilities_unittest_SOURCES = $(nodist_gloginclude_HEADERS)
+utilities_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+utilities_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+utilities_unittest_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+
+if HAVE_GMOCK
+TESTS += mock_log_test
+mock_log_test_SOURCES = $(gloginclude_HEADERS) \
+                        src/mock-log_test.cc
+nodist_mock_log_test_SOURCES = $(nodist_gloginclude_HEADERS)
+mock_log_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(TEST_CFLAGS)
+mock_log_test_LDFLAGS = $(PTHREAD_CFLAGS)
+mock_log_test_LDADD = libglog.la $(COMMON_LIBS) $(TEST_LIBS)
+endif
+
+## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
+
+lib_LTLIBRARIES += libglog.la
+libglog_la_SOURCES = $(gloginclude_HEADERS) \
+                       src/logging.cc src/raw_logging.cc src/vlog_is_on.cc \
+                       src/utilities.cc src/utilities.h \
+                       src/demangle.cc src/demangle.h \
+                       src/stacktrace.h \
+                       src/stacktrace_generic-inl.h \
+                       src/stacktrace_libunwind-inl.h \
+                       src/stacktrace_powerpc-inl.h \
+                       src/stacktrace_x86-inl.h \
+                       src/stacktrace_x86_64-inl.h \
+                       src/symbolize.cc src/symbolize.h \
+                       src/signalhandler.cc \
+                       src/base/mutex.h src/base/googleinit.h \
+                       src/base/commandlineflags.h src/googletest.h
+nodist_libglog_la_SOURCES = $(nodist_gloginclude_HEADERS)
+
+libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_CFLAGS) $(MINGW_CFLAGS) \
+                      $(AM_CXXFLAGS) -DNDEBUG
+libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_LDFLAGS)
+libglog_la_LIBADD = $(COMMON_LIBS)
+
+## The location of the windows project file for each binary we make
+WINDOWS_PROJECTS = google-glog.sln
+WINDOWS_PROJECTS += vsprojects/libglog/libglog.vcproj
+WINDOWS_PROJECTS += vsprojects/logging_unittest/logging_unittest.vcproj
+WINDOWS_PROJECTS += vsprojects/libglog_static/libglog_static.vcproj
+WINDOWS_PROJECTS += vsprojects/logging_unittest_static/logging_unittest_static.vcproj
+
+## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
+
+
+## This should always include $(TESTS), but may also include other
+## binaries that you compile but don't want automatically installed.
+noinst_PROGRAMS = $(TESTS) $(TEST_BINARIES)
+
+rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
+	@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
+
+deb: dist-gzip packages/deb.sh packages/deb/*
+	@cd packages && ./deb.sh ${PACKAGE} ${VERSION}
+
+# Windows wants write permission to .vcproj files and maybe even sln files.
+dist-hook:
+	test -e "$(distdir)/vsprojects" \
+	   && chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/
+
+libtool: $(LIBTOOL_DEPS)
+	$(SHELL) ./config.status --recheck
+
+EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec \
+	packages/deb.sh packages/deb/* \
+	$(SCRIPTS) src/logging_unittest.err src/demangle_unittest.txt \
+	src/windows/config.h src/windows/port.h src/windows/port.cc \
+	src/windows/preprocess.sh \
+	src/windows/glog/log_severity.h src/windows/glog/logging.h \
+	src/windows/glog/raw_logging.h src/windows/glog/stl_logging.h \
+	src/windows/glog/vlog_is_on.h \
+	$(WINDOWS_PROJECTS)
+
+CLEANFILES = core demangle.dm demangle.nm signalhandler.out* \
+	signalhandler_unittest.*.log.INFO.*
+
+# Add pkgconfig file
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libglog.pc
diff --git a/third_party/google-glog/README.md b/third_party/google-glog/README.md
new file mode 100644
index 0000000..d525f30
--- /dev/null
+++ b/third_party/google-glog/README.md
@@ -0,0 +1,10 @@
+[![Build Status](https://img.shields.io/travis/google/glog/master.svg?label=Travis)](https://travis-ci.org/google/glog/builds)
+[![Grunt status](https://img.shields.io/appveyor/ci/google/glog/master.svg?label=Appveyor)](https://ci.appveyor.com/project/google/glog/history)
+
+This repository contains a C++ implementation of the Google logging
+module.  Documentation for the implementation is in doc/.
+
+See INSTALL for (generic) installation instructions for C++: basically
+```sh
+./autogen.sh && ./configure && make && make install
+```
diff --git a/third_party/google-glog/README.windows b/third_party/google-glog/README.windows
new file mode 100644
index 0000000..ea6ccc2
--- /dev/null
+++ b/third_party/google-glog/README.windows
@@ -0,0 +1,17 @@
+This project has been ported to Windows, including stack tracing, signal
+handling, and unit tests.
+
+A Visual Studio solution file is explicitly not provided because it is not
+maintainable. Instead, a CMake build system exists to generate the correct
+solution for your version of Visual Studio.
+
+In short,
+  (1) Install CMake from: https://cmake.org/download/
+  (2) With CMake on your PATH, run `cmake .` to generate the build files
+  (3) Either use `cmake --build`, or open the generated solution
+
+CMake provides different generators, and by default will pick the most relevant
+one to your environment. If you need a specific version of Visual Studio, use
+`cmake . -G <generator-name>`, and see `cmake --help` for the available
+generators. Also see `-T <toolset-name>`, which can used to request the native
+x64 toolchain with `-T host=x64`.
\ No newline at end of file
diff --git a/third_party/google-glog/WORKSPACE b/third_party/google-glog/WORKSPACE
new file mode 100644
index 0000000..b5760d0
--- /dev/null
+++ b/third_party/google-glog/WORKSPACE
@@ -0,0 +1,10 @@
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+http_archive(
+    name = "com_github_gflags_gflags",
+    strip_prefix = "gflags-2.2.2",
+    urls = [
+        "https://mirror.bazel.build/github.com/gflags/gflags/archive/v2.2.2.tar.gz",
+        "https://github.com/gflags/gflags/archive/v2.2.2.tar.gz",
+    ],
+)
diff --git a/third_party/google-glog/appveyor.yml b/third_party/google-glog/appveyor.yml
new file mode 100644
index 0000000..ecc42c4
--- /dev/null
+++ b/third_party/google-glog/appveyor.yml
@@ -0,0 +1,71 @@
+# global environment variables
+environment:
+  global:
+    # path to source directory of project to be built
+    PROJECT_DIR: .
+    # output test results for failing tests
+    CTEST_OUTPUT_ON_FAILURE: 1
+
+  # test matrix
+  matrix:
+
+    - TOOLCHAIN: "vs-14-2015-sdk-8-1"
+      GENERATOR: "Visual Studio 14 2015 Win64"
+      TEST_TARGET: RUN_TESTS
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+    - TOOLCHAIN: "vs-14-2015-win64"
+      GENERATOR: "Visual Studio 14 2015 Win64"
+      TEST_TARGET: RUN_TESTS
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+    - TOOLCHAIN: "vs-15-2017-win64"
+      GENERATOR: "Visual Studio 15 2017 Win64"
+      TEST_TARGET: RUN_TESTS
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+    - TOOLCHAIN: "vs-15-2017-win64-cxx17"
+      GENERATOR: "Visual Studio 15 2017 Win64"
+      TEST_TARGET: RUN_TESTS
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+    - TOOLCHAIN: "mingw-cxx11"
+      GENERATOR: "MinGW Makefiles"
+      MINGW_PATH: "C:\\mingw-w64\\x86_64-7.2.0-posix-seh-rt_v5-rev1\\mingw64\\bin"
+      TEST_TARGET: test
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+    - TOOLCHAIN: "mingw-gnuxx11"
+      GENERATOR: "MinGW Makefiles"
+      MINGW_PATH: "C:\\mingw-w64\\x86_64-7.2.0-posix-seh-rt_v5-rev1\\mingw64\\bin"
+      TEST_TARGET: test
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+    - TOOLCHAIN: "mingw-cxx17"
+      GENERATOR: "MinGW Makefiles"
+      MINGW_PATH: "C:\\mingw-w64\\x86_64-7.2.0-posix-seh-rt_v5-rev1\\mingw64\\bin"
+      TEST_TARGET: test
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+
+install:
+  # Remove entry with sh.exe from PATH to fix error with MinGW toolchain
+  # (For MinGW make to work correctly sh.exe must NOT be in your path)
+  # * http://stackoverflow.com/a/3870338/2288008
+  - cmd: set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
+
+  # set MINGW path
+  - cmd: IF DEFINED MINGW_PATH set PATH=%MINGW_PATH%;%PATH%
+
+  # Visual Studio 15 2017: Mimic behavior of older versions
+  - cmd: set VS150COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools
+
+build_script:
+  - cmd: cmake -H. -B_build_%TOOLCHAIN%_Debug -G "%GENERATOR%" -DCMAKE_TOOLCHAIN_FILE="%cd%\toolchains\%TOOLCHAIN%.cmake"
+  - cmd: cmake --build _build_%TOOLCHAIN%_Debug --config Debug
+  #- cmd: cmake -H. -B_build_%TOOLCHAIN%_Release -G "%GENERATOR%" -DCMAKE_TOOLCHAIN_FILE="%cd%\toolchains\%TOOLCHAIN%.cmake"
+  #- cmd: cmake --build _build_%TOOLCHAIN%_Release --config Release
+  # add git back to PATH for `diff` command in case of error
+  - cmd: set PATH=C:\Program Files\Git\usr\bin;%PATH%
+  - cmd: IF DEFINED TEST_TARGET cmake --build _build_%TOOLCHAIN%_Debug --target %TEST_TARGET%
+  #- cmd: IF DEFINED TEST_TARGET cmake --build _build_%TOOLCHAIN%_Release --target %TEST_TARGET%
+
diff --git a/third_party/google-glog/autogen.sh b/third_party/google-glog/autogen.sh
new file mode 100755
index 0000000..08b6590
--- /dev/null
+++ b/third_party/google-glog/autogen.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+set -eu
+
+autoreconf -i
diff --git a/third_party/google-glog/bazel/example/BUILD b/third_party/google-glog/bazel/example/BUILD
new file mode 100644
index 0000000..6b10e2b
--- /dev/null
+++ b/third_party/google-glog/bazel/example/BUILD
@@ -0,0 +1,8 @@
+cc_test(
+    name = "main",
+    size = "small",
+    srcs = ["main.cc"],
+    deps = [
+        "//:glog",
+    ],
+)
diff --git a/third_party/google-glog/bazel/example/main.cc b/third_party/google-glog/bazel/example/main.cc
new file mode 100644
index 0000000..fef01dc
--- /dev/null
+++ b/third_party/google-glog/bazel/example/main.cc
@@ -0,0 +1,22 @@
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+#include <glog/stl_logging.h>
+
+int main(int argc, char* argv[]) {
+  // Initialize Google's logging library.
+  google::InitGoogleLogging(argv[0]);
+
+  // Optional: parse command line flags
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+
+  LOG(INFO) << "Hello, world!";
+
+  // glog/stl_logging.h allows logging STL containers.
+  std::vector<int> x;
+  x.push_back(1);
+  x.push_back(2);
+  x.push_back(3);
+  LOG(INFO) << "ABC, it's easy as " << x;
+
+  return 0;
+}
diff --git a/third_party/google-glog/bazel/glog.bzl b/third_party/google-glog/bazel/glog.bzl
new file mode 100644
index 0000000..6437619
--- /dev/null
+++ b/third_party/google-glog/bazel/glog.bzl
@@ -0,0 +1,140 @@
+# Implement a macro glog_library() that the BUILD file can load.
+
+# By default, glog is built with gflags support.  You can change this behavior
+# by using glog_library(with_gflags=0)
+#
+# This file is inspired by the following sample BUILD files:
+#       https://github.com/google/glog/issues/61
+#       https://github.com/google/glog/files/393474/BUILD.txt
+
+def glog_library(namespace='google', with_gflags=1, **kwargs):
+    if native.repository_name() != '@':
+        gendir = '$(GENDIR)/external/' + native.repository_name().lstrip('@')
+    else:
+        gendir = '$(GENDIR)'
+
+    native.cc_library(
+        name = 'glog',
+        visibility = [ '//visibility:public' ],
+        srcs = [
+            ':config_h',
+            'src/base/commandlineflags.h',
+            'src/base/googleinit.h',
+            'src/base/mutex.h',
+            'src/demangle.cc',
+            'src/demangle.h',
+            'src/logging.cc',
+            'src/raw_logging.cc',
+            'src/signalhandler.cc',
+            'src/stacktrace.h',
+            'src/stacktrace_generic-inl.h',
+            'src/stacktrace_libunwind-inl.h',
+            'src/stacktrace_powerpc-inl.h',
+            'src/stacktrace_windows-inl.h',
+            'src/stacktrace_x86-inl.h',
+            'src/stacktrace_x86_64-inl.h',
+            'src/symbolize.cc',
+            'src/symbolize.h',
+            'src/utilities.cc',
+            'src/utilities.h',
+            'src/vlog_is_on.cc',
+        ],
+        hdrs = [
+            ':logging_h',
+            ':raw_logging_h',
+            ':stl_logging_h',
+            ':vlog_is_on_h',
+            'src/glog/log_severity.h',
+        ],
+        strip_include_prefix = 'src',
+        copts = [
+            # Disable warnings that exists in glog.
+            '-Wno-sign-compare',
+            '-Wno-unused-function',
+            '-Wno-unused-local-typedefs',
+            '-Wno-unused-variable',
+            '-Wno-format-nonliteral',
+            "-DGLOG_BAZEL_BUILD",
+            # Inject a C++ namespace.
+            "-DGOOGLE_NAMESPACE='%s'" % namespace,
+            # Allows src/base/mutex.h to include pthread.h.
+            '-DHAVE_PTHREAD',
+            # Allows src/logging.cc to determine the host name.
+            '-DHAVE_SYS_UTSNAME_H',
+            # For src/utilities.cc.
+            '-DHAVE_SYS_SYSCALL_H',
+            '-DHAVE_SYS_TIME_H',
+            '-DHAVE_STDINT_H',
+            '-DHAVE_STRING_H',
+            # Enable dumping stacktrace upon sigaction.
+            '-DHAVE_SIGACTION',
+            # For logging.cc.
+            '-DHAVE_PREAD',
+            '-DHAVE___ATTRIBUTE__',
+
+            # Include generated header files.
+            '-I%s/glog_internal' % gendir,
+        ] + ([
+            # Use gflags to parse CLI arguments.
+            '-DHAVE_LIB_GFLAGS',
+        ] if with_gflags else []),
+        deps = [
+            '@com_github_gflags_gflags//:gflags',
+        ] if with_gflags else [],
+        **kwargs
+    )
+
+    native.genrule(
+        name = 'gen_sh',
+        outs = [
+            'gen.sh',
+        ],
+        cmd = r'''\
+#!/bin/sh
+cat > $@ <<"EOF"
+sed -e 's/@ac_cv_cxx_using_operator@/1/g' \
+    -e 's/@ac_cv_have_unistd_h@/1/g' \
+    -e 's/@ac_cv_have_stdint_h@/1/g' \
+    -e 's/@ac_cv_have_systypes_h@/1/g' \
+    -e 's/@ac_cv_have_libgflags@/{}/g' \
+    -e 's/@ac_cv_have_uint16_t@/1/g' \
+    -e 's/@ac_cv_have___builtin_expect@/1/g' \
+    -e 's/@ac_cv_have_.*@/0/g' \
+    -e 's/@ac_google_start_namespace@/namespace google {{/g' \
+    -e 's/@ac_google_end_namespace@/}}/g' \
+    -e 's/@ac_google_namespace@/google/g' \
+    -e 's/@ac_cv___attribute___noinline@/__attribute__((noinline))/g' \
+    -e 's/@ac_cv___attribute___noreturn@/__attribute__((noreturn))/g' \
+    -e 's/@ac_cv___attribute___printf_4_5@/__attribute__((__format__ (__printf__, 4, 5)))/g'
+EOF
+'''.format(int(with_gflags)),
+    )
+
+    native.genrule(
+        name = 'config_h',
+        srcs = [
+            'src/config.h.cmake.in',
+        ],
+        outs = [
+            'glog_internal/config.h',
+        ],
+        cmd = "awk '{ gsub(/^#cmakedefine/, \"//cmakedefine\"); print; }' $< > $@",
+    )
+
+    [native.genrule(
+        name = '%s_h' % f,
+        srcs = [
+            'src/glog/%s.h.in' % f,
+        ],
+        outs = [
+            'src/glog/%s.h' % f,
+        ],
+        cmd = '$(location :gen_sh) < $< > $@',
+        tools = [':gen_sh'],
+    ) for f in [
+            'vlog_is_on',
+            'stl_logging',
+            'raw_logging',
+            'logging',
+        ]
+    ]
diff --git a/third_party/google-glog/cmake/DetermineGflagsNamespace.cmake b/third_party/google-glog/cmake/DetermineGflagsNamespace.cmake
new file mode 100755
index 0000000..3dde42b
--- /dev/null
+++ b/third_party/google-glog/cmake/DetermineGflagsNamespace.cmake
@@ -0,0 +1,69 @@
+macro(determine_gflags_namespace VARIABLE)
+  if (NOT DEFINED "${VARIABLE}")
+    if (CMAKE_REQUIRED_INCLUDES)
+      set (CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
+    else ()
+      set (CHECK_INCLUDE_FILE_CXX_INCLUDE_DIRS)
+    endif ()
+
+    set(MACRO_CHECK_INCLUDE_FILE_FLAGS ${CMAKE_REQUIRED_FLAGS})
+
+    set(_NAMESPACES gflags google)
+    set(_check_code
+"
+#include <gflags/gflags.h>
+
+int main(int argc, char**argv)
+{
+  GLOG_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
+}
+")
+    if (NOT CMAKE_REQUIRED_QUIET)
+      message (STATUS "Looking for gflags namespace")
+    endif ()
+    if (${ARGC} EQUAL 3)
+      set (CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
+      set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARGV2}")
+    endif ()
+
+    set (_check_file
+        ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/DetermineGflagsNamespace.cxx)
+
+    foreach (_namespace ${_NAMESPACES})
+      file (WRITE "${_check_file}" "${_check_code}")
+      try_compile (${VARIABLE}
+        "${CMAKE_BINARY_DIR}" "${_check_file}"
+        COMPILE_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}" -DGLOG_GFLAGS_NAMESPACE=${_namespace}
+        LINK_LIBRARIES gflags
+        CMAKE_FLAGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+        OUTPUT_VARIABLE OUTPUT)
+
+      if (${VARIABLE})
+        set (${VARIABLE} ${_namespace} CACHE INTERNAL "gflags namespace" FORCE)
+        break ()
+      else ()
+        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+          "Determining the gflags namespace ${_namespace} failed with the following output:\n"
+          "${OUTPUT}\n\n")
+      endif ()
+    endforeach (_namespace)
+
+    if (${ARGC} EQUAL 3)
+      set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_SAVE})
+    endif ()
+
+    if (${VARIABLE})
+      if (NOT CMAKE_REQUIRED_QUIET)
+        message (STATUS "Looking for gflags namespace - ${${VARIABLE}}")
+      endif ()
+      file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Determining the gflags namespace passed with the following output:\n"
+        "${OUTPUT}\n\n")
+    else ()
+      if (NOT CMAKE_REQUIRED_QUIET)
+        message (STATUS "Looking for gflags namespace - failed")
+      endif ()
+      set (${VARIABLE} ${_namespace} CACHE INTERNAL "gflags namespace")
+    endif ()
+  endif ()
+endmacro ()
diff --git a/third_party/google-glog/cmake/INSTALL.md b/third_party/google-glog/cmake/INSTALL.md
new file mode 100644
index 0000000..a73f05e
--- /dev/null
+++ b/third_party/google-glog/cmake/INSTALL.md
@@ -0,0 +1,81 @@
+# Glog - CMake Support
+
+Glog comes with a CMake build script ([CMakeLists.txt](../CMakeLists.txt)) that can be used on a wide range of platforms.  
+If you don't have CMake installed already, you can download it for free from <http://www.cmake.org/>.
+
+CMake works by generating native makefiles or build projects that can be used in the compiler environment of your choice.  
+You can either build Glog with CMake as a standalone project or it can be incorporated into an existing CMake build for another project.
+
+## Table of Contents
+
+- [Building Glog with CMake](#building-glog-with-cmake)
+- [Consuming Glog in a CMake Project](#consuming-glog-in-a-cmake-project)
+- [Incorporating Glog into a CMake Project](#incorporating-glog-into-a-cmake-project)
+
+## Building Glog with CMake
+
+When building Glog as a standalone project, on Unix-like systems with GNU Make as build tool, the typical workflow is:  
+
+1. Get the source code and change to it.
+e.g. cloning with git:
+```bash
+git clone git@github.com:google/glog.git
+cd glog
+```
+
+2. Run CMake to configure the build tree.
+```bash
+cmake -H. -Bbuild -G "Unix Makefiles"
+```
+note: To get the list of available generators (e.g. Visual Studio), use `-G ""`
+
+3. Afterwards, generated files can be used to compile the project.
+```bash
+cmake --build build
+```
+
+4. Test the build software (optional).
+```bash
+cmake --build build --target test
+```
+
+5. Install the built files (optional).
+```bash
+cmake --build build --target install
+```
+
+## Consuming Glog in a CMake Project
+
+If you have Glog installed in your system, you can use the CMake command
+`find_package()` to include it in your CMake Project.
+
+```cmake
+cmake_minimum_required(VERSION 3.0.2)
+project(myproj VERSION 1.0)
+
+find_package(glog 0.3.5 REQUIRED)
+
+add_executable(myapp main.cpp)
+target_link_libraries(myapp glog::glog)
+```
+
+Compile definitions and options will be added automatically to your target as
+needed.
+
+## Incorporating Glog into a CMake Project
+
+You can also use the CMake command `add_subdirectory()` to include Glog directly from a subdirectory of your project.  
+The **glog::glog** target is in this case an ALIAS library target for the **glog** library target. 
+
+```cmake
+cmake_minimum_required(VERSION 3.0.2)
+project(myproj VERSION 1.0)
+
+add_subdirectory(glog)
+
+add_executable(myapp main.cpp)
+target_link_libraries(myapp glog::glog)
+```
+
+Again, compile definitions and options will be added automatically to your target as
+needed.
diff --git a/third_party/google-glog/configure.ac b/third_party/google-glog/configure.ac
new file mode 100644
index 0000000..02a767f
--- /dev/null
+++ b/third_party/google-glog/configure.ac
@@ -0,0 +1,246 @@
+## Process this file with autoconf to produce configure.
+## In general, the safest way to proceed is to run the following:
+##    % aclocal -I . -I `pwd`/../autoconf && autoheader && autoconf && automake
+
+# make sure we're interpreted by some minimal autoconf
+AC_PREREQ(2.57)
+
+AC_INIT(glog, 0.3.5, opensource@google.com)
+# The argument here is just something that should be in the current directory
+# (for sanity checking)
+AC_CONFIG_SRCDIR(README.md)
+AC_CONFIG_MACRO_DIR([m4])
+AM_INIT_AUTOMAKE
+AM_CONFIG_HEADER(src/config.h)
+
+AC_LANG(C++)
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_CXX
+AM_CONDITIONAL(GCC, test "$GCC" = yes)   # let the Makefile know if we're gcc
+
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
+# Check whether some low-level functions/files are available
+AC_HEADER_STDC
+
+# These are tested for by AC_HEADER_STDC, but I check again to set the var
+AC_CHECK_HEADER(stdint.h, ac_cv_have_stdint_h=1, ac_cv_have_stdint_h=0)
+AC_CHECK_HEADER(sys/types.h, ac_cv_have_systypes_h=1, ac_cv_have_systypes_h=0)
+AC_CHECK_HEADER(inttypes.h, ac_cv_have_inttypes_h=1, ac_cv_have_inttypes_h=0)
+AC_CHECK_HEADER(pwd.h, ac_cv_have_pwd_h=1, ac_cv_have_pwd_h=0)
+AC_CHECK_HEADERS(unistd.h, ac_cv_have_unistd_h=1, ac_cv_have_unistd_h=0)
+AC_CHECK_HEADERS(syscall.h)
+AC_CHECK_HEADERS(sys/syscall.h)
+# For backtrace with glibc.
+AC_CHECK_HEADERS(execinfo.h)
+# For backtrace with libunwind.
+AC_CHECK_HEADERS(libunwind.h, ac_cv_have_libunwind_h=1, ac_cv_have_libunwind_h=0)
+AC_CHECK_HEADERS(ucontext.h)
+AC_CHECK_HEADERS(sys/utsname.h)
+AC_CHECK_HEADERS(pwd.h)
+AC_CHECK_HEADERS(syslog.h)
+AC_CHECK_HEADERS(sys/time.h)
+AC_CHECK_HEADERS(glob.h)
+# For backtrace with gcc.
+AC_CHECK_HEADERS(unwind.h)
+
+AC_CHECK_HEADER(windows.h, ac_cv_have_windows_h=1, ac_cv_have_windows_h=0)
+if test x"$ac_cv_have_windows_h" = x"1"; then
+  MINGW_CFLAGS=-Isrc/windows
+fi
+
+AC_CHECK_SIZEOF(void *)
+
+# These are the types I need.  We look for them in either stdint.h,
+# sys/types.h, or inttypes.h, all of which are part of the default-includes.
+AC_CHECK_TYPE(uint16_t, ac_cv_have_uint16_t=1, ac_cv_have_uint16_t=0)
+AC_CHECK_TYPE(u_int16_t, ac_cv_have_u_int16_t=1, ac_cv_have_u_int16_t=0)
+AC_CHECK_TYPE(__uint16, ac_cv_have___uint16=1, ac_cv_have___uint16=0)
+
+AC_CHECK_FUNC(sigaltstack,
+              AC_DEFINE(HAVE_SIGALTSTACK, 1,
+                        [Define if you have the `sigaltstack' function]))
+AC_CHECK_FUNC(sigaction,
+              AC_DEFINE(HAVE_SIGACTION, 1,
+                        [Define if you have the 'sigaction' function]))
+AC_CHECK_FUNC(dladdr,
+              AC_DEFINE(HAVE_DLADDR, 1,
+                        [Define if you have the `dladdr' function]))
+AC_CHECK_FUNC(fcntl,
+              AC_DEFINE(HAVE_FCNTL, 1,
+                        [Define if you have the `fcntl' function]))
+AC_CHECK_FUNC(pread,
+              AC_DEFINE(HAVE_PREAD, 1,
+                        [Define if you have the 'pread' function]))
+AC_CHECK_FUNC(pwrite,
+              AC_DEFINE(HAVE_PWRITE, 1,
+                        [Define if you have the 'pwrite' function]))
+
+AX_C___ATTRIBUTE__
+# We only care about these two attributes.
+if test x"$ac_cv___attribute__" = x"yes"; then
+  ac_cv___attribute___noreturn="__attribute__ ((noreturn))"
+  ac_cv___attribute___noinline="__attribute__ ((noinline))"
+  ac_cv___attribute___printf_4_5="__attribute__((__format__ (__printf__, 4, 5)))"
+else
+  ac_cv___attribute___noreturn=
+  ac_cv___attribute___noinline=
+  ac_cv___attribute___printf_4_5=
+fi
+
+AX_C___BUILTIN_EXPECT
+if test x"$ac_cv___builtin_expect" = x"yes"; then
+  ac_cv_have___builtin_expect=1
+else
+  ac_cv_have___builtin_expect=0
+fi
+
+AX_C___SYNC_VAL_COMPARE_AND_SWAP
+
+# On x86_64, instead of libunwind, we can choose to compile with frame-pointers
+# (This isn't needed on i386, where -fno-omit-frame-pointer is the default).
+AC_ARG_ENABLE(frame_pointers,
+              AS_HELP_STRING([--enable-frame-pointers],
+                             [On x86_64 systems, compile with -fno-omit-frame-pointer (see INSTALL)]),,
+              enable_frame_pointers=no)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __x86_64__ == 1 ? 0 : 1])],
+                  [is_x86_64=yes], [is_x86_64=no])
+AM_CONDITIONAL(ENABLE_FRAME_POINTERS, test "$enable_frame_pointers" = yes)
+AM_CONDITIONAL(X86_64, test "$is_x86_64" = yes)
+
+AC_ARG_ENABLE(rtti,
+              AS_HELP_STRING([--disable-rtti],
+                             [Disable RTTI in glog]))
+AM_CONDITIONAL(DISABLE_RTTI, test x"$enable_rtti" = x"no")
+if test x"$enable_rtti" = x"no"; then
+  AC_DEFINE(DISABLE_RTTI, 1, [define if glog doesn't use RTTI])
+fi
+
+# Some of the code in this directory depends on pthreads
+ACX_PTHREAD
+if test x"$acx_pthread_ok" = x"yes"; then
+  # To make libglog depend on libpthread on Linux, we need to add
+  # -lpthread in addition to -pthread.
+  AC_CHECK_LIB(pthread, pthread_self)
+fi
+
+# Check if there is google-gflags library installed.
+SAVE_CFLAGS="$CFLAGS"
+SAVE_LIBS="$LIBS"
+AC_ARG_WITH(gflags, AS_HELP_STRING[--with-gflags=GFLAGS_DIR],
+  GFLAGS_CFLAGS="-I${with_gflags}/include"
+  GFLAGS_LIBS="-L${with_gflags}/lib -lgflags"
+  CFLAGS="$CFLAGS $GFLAGS_CFLAGS"
+  LIBS="$LIBS $GFLAGS_LIBS"
+)
+AC_CHECK_LIB(gflags, main, ac_cv_have_libgflags=1, ac_cv_have_libgflags=0)
+if test x"$ac_cv_have_libgflags" = x"1"; then
+  AC_DEFINE(HAVE_LIB_GFLAGS, 1, [define if you have google gflags library])
+  if test x"$GFLAGS_LIBS" = x""; then
+    GFLAGS_LIBS="-lgflags"
+  fi
+else
+  GFLAGS_CFLAGS=
+  GFLAGS_LIBS=
+fi
+CFLAGS="$SAVE_CFLAGS"
+LIBS="$SAVE_LIBS"
+
+# TODO(hamaji): Use official m4 macros provided by testing libraries
+#               once the m4 macro of Google Mocking becomes ready.
+# Check if there is Google Test library installed.
+AC_CHECK_PROG(GTEST_CONFIG, gtest-config, "yes")
+AC_CHECK_LIB(gtest, main, have_gtest_lib="yes")
+if test x"$GTEST_CONFIG" = "xyes" -a x"$have_gtest_lib" = "xyes"; then
+  GTEST_CFLAGS=`gtest-config --cppflags --cxxflags`
+  GTEST_LIBS=`gtest-config --ldflags --libs`
+  AC_DEFINE(HAVE_LIB_GTEST, 1, [define if you have google gtest library])
+
+  # Check if there is Google Mocking library installed.
+  AC_CHECK_PROG(GMOCK_CONFIG, gmock-config, "yes")
+  if test x"$GMOCK_CONFIG" = "xyes"; then
+    GMOCK_CFLAGS=`gmock-config --cppflags --cxxflags`
+    GMOCK_LIBS=`gmock-config --ldflags --libs`
+    AC_DEFINE(HAVE_LIB_GMOCK, 1, [define if you have google gmock library])
+  else
+    # We don't run test cases which use Google Mocking framework.
+    GMOCK_CFLAGS=
+    GMOCK_LIBS=
+  fi
+else
+  # We'll use src/googletest.h for our unittests.
+  GTEST_CFLAGS=
+  GTEST_LIBS=
+fi
+AM_CONDITIONAL(HAVE_GMOCK, test x"$GMOCK_CONFIG" = "xyes")
+
+# We want to link in libunwind if it exists
+UNWIND_LIBS=
+# Unfortunately, we need to check the header file in addition to the
+# lib file to check if libunwind is available since libunwind-0.98
+# doesn't install all necessary header files.
+if test x"$ac_cv_have_libunwind_h" = x"1"; then
+ AC_CHECK_LIB(unwind, backtrace, UNWIND_LIBS=-lunwind)
+fi
+AC_SUBST(UNWIND_LIBS)
+if test x"$UNWIND_LIBS" != x""; then
+  AC_DEFINE(HAVE_LIB_UNWIND, 1, [define if you have libunwind])
+fi
+
+# We'd like to use read/write locks in several places in the code.
+# See if our pthreads support extends to that.  Note: for linux, it
+# does as long as you define _XOPEN_SOURCE appropriately.
+AC_RWLOCK
+
+# Find out what namespace 'normal' STL code lives in, and also what namespace
+# the user wants our classes to be defined in
+AC_CXX_STL_NAMESPACE
+AC_DEFINE_GOOGLE_NAMESPACE(google)
+
+AC_CXX_USING_OPERATOR
+
+AC_PC_FROM_UCONTEXT(AC_MSG_WARN(Could not find the PC.  Will not output failed addresses...))
+
+AC_DEFINE_UNQUOTED(TEST_SRC_DIR, "$srcdir", [location of source code])
+
+AC_ARG_ENABLE(unsymbolized-traces,
+              AS_HELP_STRING([--enable-unsymbolized-traces],
+                             [Print raw pc values when symbolization is failed.]),
+              enable_unsymbolized_traces=yes)
+if test x"$enable_unsymbolized_traces" = x"yes"; then
+  AC_DEFINE(PRINT_UNSYMBOLIZED_STACK_TRACES, 1,
+            [define if we should print raw pc values on symbolization failure.])
+fi
+
+# These are what's needed by logging.h.in and raw_logging.h.in
+AC_SUBST(ac_google_start_namespace)
+AC_SUBST(ac_google_end_namespace)
+AC_SUBST(ac_google_namespace)
+AC_SUBST(ac_cv_cxx_using_operator)
+AC_SUBST(ac_cv___attribute___noreturn)
+AC_SUBST(ac_cv___attribute___noinline)
+AC_SUBST(ac_cv___attribute___printf_4_5)
+AC_SUBST(ac_cv_have___builtin_expect)
+AC_SUBST(ac_cv_have_stdint_h)
+AC_SUBST(ac_cv_have_systypes_h)
+AC_SUBST(ac_cv_have_inttypes_h)
+AC_SUBST(ac_cv_have_unistd_h)
+AC_SUBST(ac_cv_have_uint16_t)
+AC_SUBST(ac_cv_have_u_int16_t)
+AC_SUBST(ac_cv_have___uint16)
+AC_SUBST(ac_cv_have_libgflags)
+AC_SUBST(GFLAGS_CFLAGS)
+AC_SUBST(GTEST_CFLAGS)
+AC_SUBST(GMOCK_CFLAGS)
+AC_SUBST(MINGW_CFLAGS)
+AC_SUBST(GFLAGS_LIBS)
+AC_SUBST(GTEST_LIBS)
+AC_SUBST(GMOCK_LIBS)
+
+# Write generated configuration file
+AC_CONFIG_FILES([Makefile src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h])
+AC_OUTPUT(libglog.pc)
diff --git a/third_party/google-glog/doc/designstyle.css b/third_party/google-glog/doc/designstyle.css
new file mode 100644
index 0000000..f5d1ec2
--- /dev/null
+++ b/third_party/google-glog/doc/designstyle.css
@@ -0,0 +1,115 @@
+body {
+  background-color: #ffffff;
+  color: black;
+  margin-right: 1in;
+  margin-left: 1in;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+  color: #3366ff;
+  font-family: sans-serif;
+}
+@media print {
+  /* Darker version for printing */
+  h1, h2, h3, h4, h5, h6 {
+    color: #000080;
+    font-family: helvetica, sans-serif;
+  }
+}
+
+h1 { 
+  text-align: center;
+  font-size: 18pt;
+}
+h2 {
+  margin-left: -0.5in;
+}
+h3 {
+  margin-left: -0.25in;
+}
+h4 {
+  margin-left: -0.125in;
+}
+hr {
+  margin-left: -1in;
+}
+
+/* Definition lists: definition term bold */
+dt {
+  font-weight: bold;
+}
+
+address {
+  text-align: right;
+}
+/* Use the <code> tag for bits of code and <var> for variables and objects. */
+code,pre,samp,var {
+  color: #006000;
+}
+/* Use the <file> tag for file and directory paths and names. */
+file {
+  color: #905050;
+  font-family: monospace;
+}
+/* Use the <kbd> tag for stuff the user should type. */
+kbd {
+  color: #600000;
+}
+div.note p {
+  float: right;
+  width: 3in;
+  margin-right: 0%;
+  padding: 1px;
+  border: 2px solid #6060a0;
+  background-color: #fffff0;
+}
+
+UL.nobullets {
+  list-style-type: none;
+  list-style-image: none;
+  margin-left: -1em;
+}
+
+/*
+body:after {
+  content: "Google Confidential";
+}
+*/
+
+/* pretty printing styles.  See prettify.js */
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+.tag { color: #008; }
+.atn { color: #606; }
+.atv { color: #080; }
+pre.prettyprint { padding: 2px; border: 1px solid #888; }
+
+.embsrc { background: #eee; }
+
+@media print {
+  .str { color: #060; }
+  .kwd { color: #006; font-weight: bold; }
+  .com { color: #600; font-style: italic; }
+  .typ { color: #404; font-weight: bold; }
+  .lit { color: #044; }
+  .pun { color: #440; }
+  .pln { color: #000; }
+  .tag { color: #006; font-weight: bold; }
+  .atn { color: #404; }
+  .atv { color: #060; }
+}
+
+/* Table Column Headers */
+.hdr { 
+  color: #006; 
+  font-weight: bold; 
+  background-color: #dddddd; }
+.hdr2 { 
+  color: #006; 
+  background-color: #eeeeee; }
\ No newline at end of file
diff --git a/third_party/google-glog/doc/glog.html b/third_party/google-glog/doc/glog.html
new file mode 100644
index 0000000..0edaa66
--- /dev/null
+++ b/third_party/google-glog/doc/glog.html
@@ -0,0 +1,613 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+<title>How To Use Google Logging Library (glog)</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link href="http://www.google.com/favicon.ico" type="image/x-icon"
+      rel="shortcut icon">
+<link href="designstyle.css" type="text/css" rel="stylesheet">
+<style type="text/css">
+<!--
+  ol.bluelist li {
+    color: #3366ff;
+    font-family: sans-serif;
+  }
+  ol.bluelist li p {
+    color: #000;
+    font-family: "Times Roman", times, serif;
+  }
+  ul.blacklist li {
+    color: #000;
+    font-family: "Times Roman", times, serif;
+  }
+//-->
+</style>
+</head>
+
+<body>
+
+<h1>How To Use Google Logging Library (glog)</h1>
+<small>(as of
+<script type=text/javascript>
+  var lm = new Date(document.lastModified);
+  document.write(lm.toDateString());
+</script>)
+</small>
+<br>
+
+<h2> <A NAME=intro>Introduction</A> </h2>
+
+<p><b>Google glog</b> is a library that implements application-level
+logging.  This library provides logging APIs based on C++-style
+streams and various helper macros.
+You can log a message by simply streaming things to LOG(&lt;a
+particular <a href="#severity">severity level</a>&gt;), e.g.
+
+<pre>
+   #include &lt;glog/logging.h&gt;
+
+   int main(int argc, char* argv[]) {
+     // Initialize Google's logging library.
+     google::InitGoogleLogging(argv[0]);
+
+     // ...
+     LOG(INFO) &lt;&lt; "Found " &lt;&lt; num_cookies &lt;&lt; " cookies";
+   }
+</pre>
+
+<p>Google glog defines a series of macros that simplify many common logging
+tasks.  You can log messages by severity level, control logging
+behavior from the command line, log based on conditionals, abort the
+program when expected conditions are not met, introduce your own
+verbose logging levels, and more.  This document describes the
+functionality supported by glog.  Please note that this document
+doesn't describe all features in this library, but the most useful
+ones.  If you want to find less common features, please check
+header files under <code>src/glog</code> directory.
+
+<h2> <A NAME=severity>Severity Level</A> </h2>
+
+<p>
+You can specify one of the following severity levels (in
+increasing order of severity): <code>INFO</code>, <code>WARNING</code>,
+<code>ERROR</code>, and <code>FATAL</code>.
+Logging a <code>FATAL</code> message terminates the program (after the
+message is logged).
+Note that messages of a given severity are logged not only in the
+logfile for that severity, but also in all logfiles of lower severity.
+E.g., a message of severity <code>FATAL</code> will be logged to the
+logfiles of severity <code>FATAL</code>, <code>ERROR</code>,
+<code>WARNING</code>, and <code>INFO</code>.
+
+<p>
+The <code>DFATAL</code> severity logs a <code>FATAL</code> error in
+debug mode (i.e., there is no <code>NDEBUG</code> macro defined), but
+avoids halting the program in production by automatically reducing the
+severity to <code>ERROR</code>.
+
+<p>Unless otherwise specified, glog writes to the filename
+"/tmp/&lt;program name&gt;.&lt;hostname&gt;.&lt;user name&gt;.log.&lt;severity level&gt;.&lt;date&gt;.&lt;time&gt;.&lt;pid&gt;"
+(e.g., "/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474").
+By default, glog copies the log messages of severity level
+<code>ERROR</code> or <code>FATAL</code> to standard error (stderr)
+in addition to log files.
+
+<h2><A NAME=flags>Setting Flags</A></h2>
+
+<p>Several flags influence glog's output behavior.
+If the <a href="https://github.com/gflags/gflags">Google
+gflags library</a> is installed on your machine, the
+<code>configure</code> script (see the INSTALL file in the package for
+detail of this script) will automatically detect and use it,
+allowing you to pass flags on the command line.  For example, if you
+want to turn the flag <code>--logtostderr</code> on, you can start
+your application with the following command line:
+
+<pre>
+   ./your_application --logtostderr=1
+</pre>
+
+If the Google gflags library isn't installed, you set flags via
+environment variables, prefixing the flag name with "GLOG_", e.g.
+
+<pre>
+   GLOG_logtostderr=1 ./your_application
+</pre>
+
+<!-- TODO(hamaji): Fill the version number
+<p>By glog version 0.x.x, you can use GLOG_* environment variables
+even if you have gflags. If both an environment variable and a flag
+are specified, the value specified by a flag wins. E.g., if GLOG_v=0
+and --v=1, the verbosity will be 1, not 0.
+-->
+
+<p>The following flags are most commonly used:
+
+<dl>
+<dt><code>logtostderr</code> (<code>bool</code>, default=<code>false</code>)
+<dd>Log messages to stderr instead of logfiles.<br>
+Note: you can set binary flags to <code>true</code> by specifying
+<code>1</code>, <code>true</code>, or <code>yes</code> (case
+insensitive).
+Also, you can set binary flags to <code>false</code> by specifying
+<code>0</code>, <code>false</code>, or <code>no</code> (again, case
+insensitive).
+<dt><code>stderrthreshold</code> (<code>int</code>, default=2, which
+is <code>ERROR</code>)
+<dd>Copy log messages at or above this level to stderr in
+addition to logfiles.  The numbers of severity levels
+<code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>, and
+<code>FATAL</code> are 0, 1, 2, and 3, respectively.
+<dt><code>minloglevel</code> (<code>int</code>, default=0, which
+is <code>INFO</code>)
+<dd>Log messages at or above this level.  Again, the numbers of
+severity levels <code>INFO</code>, <code>WARNING</code>,
+<code>ERROR</code>, and <code>FATAL</code> are 0, 1, 2, and 3,
+respectively.
+<dt><code>log_dir</code> (<code>string</code>, default="")
+<dd>If specified, logfiles are written into this directory instead
+of the default logging directory.
+<dt><code>v</code> (<code>int</code>, default=0)
+<dd>Show all <code>VLOG(m)</code> messages for <code>m</code> less or
+equal the value of this flag.  Overridable by --vmodule.
+See <a href="#verbose">the section about verbose logging</a> for more
+detail.
+<dt><code>vmodule</code> (<code>string</code>, default="")
+<dd>Per-module verbose level.  The argument has to contain a
+comma-separated list of &lt;module name&gt;=&lt;log level&gt;.
+&lt;module name&gt;
+is a glob pattern (e.g., <code>gfs*</code> for all modules whose name
+starts with "gfs"), matched against the filename base
+(that is, name ignoring .cc/.h./-inl.h).
+&lt;log level&gt; overrides any value given by --v.
+See also <a href="#verbose">the section about verbose logging</a>.
+</dl>
+
+<p>There are some other flags defined in logging.cc.  Please grep the
+source code for "DEFINE_" to see a complete list of all flags.
+
+<p>You can also modify flag values in your program by modifying global
+variables <code>FLAGS_*</code> . Most settings start working
+immediately after you update <code>FLAGS_*</code> . The exceptions are
+the flags related to destination files. For example, you might want to
+set <code>FLAGS_log_dir</code> before
+calling <code>google::InitGoogleLogging</code> . Here is an example:
+
+<pre>
+   LOG(INFO) << "file";
+   // Most flags work immediately after updating values.
+   FLAGS_logtostderr = 1;
+   LOG(INFO) << "stderr";
+   FLAGS_logtostderr = 0;
+   // This won't change the log destination. If you want to set this
+   // value, you should do this before google::InitGoogleLogging .
+   FLAGS_log_dir = "/some/log/directory";
+   LOG(INFO) << "the same file";
+</pre>
+
+<h2><A NAME=conditional>Conditional / Occasional Logging</A></h2>
+
+<p>Sometimes, you may only want to log a message under certain
+conditions. You can use the following macros to perform conditional
+logging:
+
+<pre>
+   LOG_IF(INFO, num_cookies &gt; 10) &lt;&lt; "Got lots of cookies";
+</pre>
+
+The "Got lots of cookies" message is logged only when the variable
+<code>num_cookies</code> exceeds 10.
+
+If a line of code is executed many times, it may be useful to only log
+a message at certain intervals.  This kind of logging is most useful
+for informational messages.
+
+<pre>
+   LOG_EVERY_N(INFO, 10) &lt;&lt; "Got the " &lt;&lt; google::COUNTER &lt;&lt; "th cookie";
+</pre>
+
+<p>The above line outputs a log messages on the 1st, 11th,
+21st, ... times it is executed.  Note that the special
+<code>google::COUNTER</code> value is used to identify which repetition is
+happening.
+
+<p>You can combine conditional and occasional logging with the
+following macro.
+
+<pre>
+   LOG_IF_EVERY_N(INFO, (size &gt; 1024), 10) &lt;&lt; "Got the " &lt;&lt; google::COUNTER
+                                           &lt;&lt; "th big cookie";
+</pre>
+
+<p>Instead of outputting a message every nth time, you can also limit
+the output to the first n occurrences:
+
+<pre>
+   LOG_FIRST_N(INFO, 20) &lt;&lt; "Got the " &lt;&lt; google::COUNTER &lt;&lt; "th cookie";
+</pre>
+
+<p>Outputs log messages for the first 20 times it is executed.  Again,
+the <code>google::COUNTER</code> identifier indicates which repetition is
+happening.
+
+<h2><A NAME=debug>Debug Mode Support</A></h2>
+
+<p>Special "debug mode" logging macros only have an effect in debug
+mode and are compiled away to nothing for non-debug mode
+compiles.  Use these macros to avoid slowing down your production
+application due to excessive logging.
+
+<pre>
+   DLOG(INFO) &lt;&lt; "Found cookies";
+
+   DLOG_IF(INFO, num_cookies &gt; 10) &lt;&lt; "Got lots of cookies";
+
+   DLOG_EVERY_N(INFO, 10) &lt;&lt; "Got the " &lt;&lt; google::COUNTER &lt;&lt; "th cookie";
+</pre>
+
+<h2><A NAME=check>CHECK Macros</A></h2>
+
+<p>It is a good practice to check expected conditions in your program
+frequently to detect errors as early as possible. The
+<code>CHECK</code> macro provides the ability to abort the application
+when a condition is not met, similar to the <code>assert</code> macro
+defined in the standard C library.
+
+<p><code>CHECK</code> aborts the application if a condition is not
+true.  Unlike <code>assert</code>, it is *not* controlled by
+<code>NDEBUG</code>, so the check will be executed regardless of
+compilation mode.  Therefore, <code>fp-&gt;Write(x)</code> in the
+following example is always executed:
+
+<pre>
+   CHECK(fp-&gt;Write(x) == 4) &lt;&lt; "Write failed!";
+</pre>
+
+<p>There are various helper macros for
+equality/inequality checks - <code>CHECK_EQ</code>,
+<code>CHECK_NE</code>, <code>CHECK_LE</code>, <code>CHECK_LT</code>,
+<code>CHECK_GE</code>, and <code>CHECK_GT</code>.
+They compare two values, and log a
+<code>FATAL</code> message including the two values when the result is
+not as expected.  The values must have <code>operator&lt;&lt;(ostream,
+...)</code> defined.
+
+<p>You may append to the error message like so:
+
+<pre>
+   CHECK_NE(1, 2) &lt;&lt; ": The world must be ending!";
+</pre>
+
+<p>We are very careful to ensure that each argument is evaluated exactly
+once, and that anything which is legal to pass as a function argument is
+legal here.  In particular, the arguments may be temporary expressions
+which will end up being destroyed at the end of the apparent statement,
+for example:
+
+<pre>
+   CHECK_EQ(string("abc")[1], 'b');
+</pre>
+
+<p>The compiler reports an error if one of the arguments is a
+pointer and the other is NULL. To work around this, simply static_cast
+NULL to the type of the desired pointer.
+
+<pre>
+   CHECK_EQ(some_ptr, static_cast&lt;SomeType*&gt;(NULL));
+</pre>
+
+<p>Better yet, use the CHECK_NOTNULL macro:
+
+<pre>
+   CHECK_NOTNULL(some_ptr);
+   some_ptr-&gt;DoSomething();
+</pre>
+
+<p>Since this macro returns the given pointer, this is very useful in
+constructor initializer lists.
+
+<pre>
+   struct S {
+     S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)) {}
+     Something* ptr_;
+   };
+</pre>
+
+<p>Note that you cannot use this macro as a C++ stream due to this
+feature.  Please use <code>CHECK_EQ</code> described above to log a
+custom message before aborting the application.
+
+<p>If you are comparing C strings (char *), a handy set of macros
+performs case sensitive as well as case insensitive comparisons -
+<code>CHECK_STREQ</code>, <code>CHECK_STRNE</code>,
+<code>CHECK_STRCASEEQ</code>, and <code>CHECK_STRCASENE</code>.  The
+CASE versions are case-insensitive.  You can safely pass <code>NULL</code>
+pointers for this macro.  They treat <code>NULL</code> and any
+non-<code>NULL</code> string as not equal.  Two <code>NULL</code>s are
+equal.
+
+<p>Note that both arguments may be temporary strings which are
+destructed at the end of the current "full expression"
+(e.g., <code>CHECK_STREQ(Foo().c_str(), Bar().c_str())</code> where
+<code>Foo</code> and <code>Bar</code> return C++'s
+<code>std::string</code>).
+
+<p>The <code>CHECK_DOUBLE_EQ</code> macro checks the equality of two
+floating point values, accepting a small error margin.
+<code>CHECK_NEAR</code> accepts a third floating point argument, which
+specifies the acceptable error margin.
+
+<h2><A NAME=verbose>Verbose Logging</A></h2>
+
+<p>When you are chasing difficult bugs, thorough log messages are very
+useful.  However, you may want to ignore too verbose messages in usual
+development.  For such verbose logging, glog provides the
+<code>VLOG</code> macro, which allows you to define your own numeric
+logging levels.  The <code>--v</code> command line option controls
+which verbose messages are logged:
+
+<pre>
+   VLOG(1) &lt;&lt; "I'm printed when you run the program with --v=1 or higher";
+   VLOG(2) &lt;&lt; "I'm printed when you run the program with --v=2 or higher";
+</pre>
+
+<p>With <code>VLOG</code>, the lower the verbose level, the more
+likely messages are to be logged.  For example, if
+<code>--v==1</code>, <code>VLOG(1)</code> will log, but
+<code>VLOG(2)</code> will not log.  This is opposite of the severity
+level, where <code>INFO</code> is 0, and <code>ERROR</code> is 2.
+<code>--minloglevel</code> of 1 will log <code>WARNING</code> and
+above.  Though you can specify any integers for both <code>VLOG</code>
+macro and <code>--v</code> flag, the common values for them are small
+positive integers.  For example, if you write <code>VLOG(0)</code>,
+you should specify <code>--v=-1</code> or lower to silence it.  This
+is less useful since we may not want verbose logs by default in most
+cases.  The <code>VLOG</code> macros always log at the
+<code>INFO</code> log level (when they log at all).
+
+<p>Verbose logging can be controlled from the command line on a
+per-module basis:
+
+<pre>
+   --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
+</pre>
+
+<p>will:
+
+<ul>
+  <li>a. Print VLOG(2) and lower messages from mapreduce.{h,cc}
+  <li>b. Print VLOG(1) and lower messages from file.{h,cc}
+  <li>c. Print VLOG(3) and lower messages from files prefixed with "gfs"
+  <li>d. Print VLOG(0) and lower messages from elsewhere
+</ul>
+
+<p>The wildcarding functionality shown by (c) supports both '*'
+(matches 0 or more characters) and '?' (matches any single character)
+wildcards.  Please also check the section about <a
+href="#flags">command line flags</a>.
+
+<p>There's also <code>VLOG_IS_ON(n)</code> "verbose level" condition
+macro.  This macro returns true when the <code>--v</code> is equal or
+greater than <code>n</code>.  To be used as
+
+<pre>
+   if (VLOG_IS_ON(2)) {
+     // do some logging preparation and logging
+     // that can't be accomplished with just VLOG(2) &lt;&lt; ...;
+   }
+</pre>
+
+<p>Verbose level condition macros <code>VLOG_IF</code>,
+<code>VLOG_EVERY_N</code> and <code>VLOG_IF_EVERY_N</code> behave
+analogous to <code>LOG_IF</code>, <code>LOG_EVERY_N</code>,
+<code>LOF_IF_EVERY</code>, but accept a numeric verbosity level as
+opposed to a severity level.
+
+<pre>
+   VLOG_IF(1, (size &gt; 1024))
+      &lt;&lt; "I'm printed when size is more than 1024 and when you run the "
+         "program with --v=1 or more";
+   VLOG_EVERY_N(1, 10)
+      &lt;&lt; "I'm printed every 10th occurrence, and when you run the program "
+         "with --v=1 or more. Present occurence is " &lt;&lt; google::COUNTER;
+   VLOG_IF_EVERY_N(1, (size &gt; 1024), 10)
+      &lt;&lt; "I'm printed on every 10th occurence of case when size is more "
+         " than 1024, when you run the program with --v=1 or more. ";
+         "Present occurence is " &lt;&lt; google::COUNTER;
+</pre>
+
+<h2> <A name="signal">Failure Signal Handler</A> </h2>
+
+<p>
+The library provides a convenient signal handler that will dump useful
+information when the program crashes on certain signals such as SIGSEGV.
+The signal handler can be installed by
+google::InstallFailureSignalHandler().  The following is an example of output
+from the signal handler.
+
+<pre>
+*** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date ***
+*** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: ***
+PC: @           0x412eb1 TestWaitingLogSink::send()
+    @     0x7f892fb417d0 (unknown)
+    @           0x412eb1 TestWaitingLogSink::send()
+    @     0x7f89304f7f06 google::LogMessage::SendToLog()
+    @     0x7f89304f35af google::LogMessage::Flush()
+    @     0x7f89304f3739 google::LogMessage::~LogMessage()
+    @           0x408cf4 TestLogSinkWaitTillSent()
+    @           0x4115de main
+    @     0x7f892f7ef1c4 (unknown)
+    @           0x4046f9 (unknown)
+</pre>
+
+<p>
+By default, the signal handler writes the failure dump to the standard
+error.  You can customize the destination by InstallFailureWriter().
+
+<h2> <A name="misc">Miscellaneous Notes</A> </h2>
+
+<h3><A NAME=message>Performance of Messages</A></h3>
+
+<p>The conditional logging macros provided by glog (e.g.,
+<code>CHECK</code>, <code>LOG_IF</code>, <code>VLOG</code>, ...) are
+carefully implemented and don't execute the right hand side
+expressions when the conditions are false.  So, the following check
+may not sacrifice the performance of your application.
+
+<pre>
+   CHECK(obj.ok) &lt;&lt; obj.CreatePrettyFormattedStringButVerySlow();
+</pre>
+
+<h3><A NAME=failure>User-defined Failure Function</A></h3>
+
+<p><code>FATAL</code> severity level messages or unsatisfied
+<code>CHECK</code> condition terminate your program.  You can change
+the behavior of the termination by
+<code>InstallFailureFunction</code>.
+
+<pre>
+   void YourFailureFunction() {
+     // Reports something...
+     exit(1);
+   }
+
+   int main(int argc, char* argv[]) {
+     google::InstallFailureFunction(&amp;YourFailureFunction);
+   }
+</pre>
+
+<p>By default, glog tries to dump stacktrace and makes the program
+exit with status 1.  The stacktrace is produced only when you run the
+program on an architecture for which glog supports stack tracing (as
+of September 2008, glog supports stack tracing for x86 and x86_64).
+
+<h3><A NAME=raw>Raw Logging</A></h3>
+
+<p>The header file <code>&lt;glog/raw_logging.h&gt;</code> can be
+used for thread-safe logging, which does not allocate any memory or
+acquire any locks.  Therefore, the macros defined in this
+header file can be used by low-level memory allocation and
+synchronization code.
+Please check <code>src/glog/raw_logging.h.in</code> for detail.
+</p>
+
+<h3><A NAME=plog>Google Style perror()</A></h3>
+
+<p><code>PLOG()</code> and <code>PLOG_IF()</code> and
+<code>PCHECK()</code> behave exactly like their <code>LOG*</code> and
+<code>CHECK</code> equivalents with the addition that they append a
+description of the current state of errno to their output lines.
+E.g.
+
+<pre>
+   PCHECK(write(1, NULL, 2) &gt;= 0) &lt;&lt; "Write NULL failed";
+</pre>
+
+<p>This check fails with the following error message.
+
+<pre>
+   F0825 185142 test.cc:22] Check failed: write(1, NULL, 2) &gt;= 0 Write NULL failed: Bad address [14]
+</pre>
+
+<h3><A NAME=syslog>Syslog</A></h3>
+
+<p><code>SYSLOG</code>, <code>SYSLOG_IF</code>, and
+<code>SYSLOG_EVERY_N</code> macros are available.
+These log to syslog in addition to the normal logs.  Be aware that
+logging to syslog can drastically impact performance, especially if
+syslog is configured for remote logging!  Make sure you understand the
+implications of outputting to syslog before you use these macros. In
+general, it's wise to use these macros sparingly.
+
+<h3><A NAME=strip>Strip Logging Messages</A></h3>
+
+<p>Strings used in log messages can increase the size of your binary
+and present a privacy concern.  You can therefore instruct glog to
+remove all strings which fall below a certain severity level by using
+the GOOGLE_STRIP_LOG macro:
+
+<p>If your application has code like this:
+
+<pre>
+   #define GOOGLE_STRIP_LOG 1    // this must go before the #include!
+   #include &lt;glog/logging.h&gt;
+</pre>
+
+<p>The compiler will remove the log messages whose severities are less
+than the specified integer value.  Since
+<code>VLOG</code> logs at the severity level <code>INFO</code>
+(numeric value <code>0</code>),
+setting <code>GOOGLE_STRIP_LOG</code> to 1 or greater removes
+all log messages associated with <code>VLOG</code>s as well as
+<code>INFO</code> log statements.
+
+<h3><A NAME=windows>Notes for Windows users</A></h3>
+
+<p>Google glog defines a severity level <code>ERROR</code>, which is
+also defined in <code>windows.h</code> . You can make glog not define
+<code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>,
+and <code>FATAL</code> by defining
+<code>GLOG_NO_ABBREVIATED_SEVERITIES</code> before
+including <code>glog/logging.h</code> . Even with this macro, you can
+still use the iostream like logging facilities:
+
+<pre>
+  #define GLOG_NO_ABBREVIATED_SEVERITIES
+  #include &lt;windows.h&gt;
+  #include &lt;glog/logging.h&gt;
+
+  // ...
+
+  LOG(ERROR) &lt;&lt; "This should work";
+  LOG_IF(ERROR, x &gt; y) &lt;&lt; "This should be also OK";
+</pre>
+
+<p>
+However, you cannot
+use <code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>,
+and <code>FATAL</code> anymore for functions defined
+in <code>glog/logging.h</code> .
+
+<pre>
+  #define GLOG_NO_ABBREVIATED_SEVERITIES
+  #include &lt;windows.h&gt;
+  #include &lt;glog/logging.h&gt;
+
+  // ...
+
+  // This won't work.
+  // google::FlushLogFiles(google::ERROR);
+
+  // Use this instead.
+  google::FlushLogFiles(google::GLOG_ERROR);
+</pre>
+
+<p>
+If you don't need <code>ERROR</code> defined
+by <code>windows.h</code>, there are a couple of more workarounds
+which sometimes don't work:
+
+<ul>
+  <li>#define <code>WIN32_LEAN_AND_MEAN</code> or <code>NOGDI</code>
+      <strong>before</strong> you #include <code>windows.h</code> .
+  <li>#undef <code>ERROR</code> <strong>after</strong> you #include
+      <code>windows.h</code> .
+</ul>
+
+<p>See <a href="http://code.google.com/p/google-glog/issues/detail?id=33">
+this issue</a> for more detail.
+
+<hr>
+<address>
+Shinichiro Hamaji<br>
+Gregor Hohpe<br>
+<script type=text/javascript>
+  var lm = new Date(document.lastModified);
+  document.write(lm.toDateString());
+</script>
+</address>
+
+</body>
+</html>
diff --git a/third_party/google-glog/glog-config.cmake.in b/third_party/google-glog/glog-config.cmake.in
new file mode 100644
index 0000000..aabdedc
--- /dev/null
+++ b/third_party/google-glog/glog-config.cmake.in
@@ -0,0 +1,11 @@
+if (CMAKE_VERSION VERSION_LESS @glog_CMake_VERSION@)
+  message (FATAL_ERROR "CMake >= @glog_CMake_VERSION@ required")
+endif (CMAKE_VERSION VERSION_LESS @glog_CMake_VERSION@)
+
+@PACKAGE_INIT@
+
+include (CMakeFindDependencyMacro)
+
+@gflags_DEPENDENCY@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/glog-targets.cmake")
diff --git a/third_party/google-glog/libglog.pc.in b/third_party/google-glog/libglog.pc.in
new file mode 100644
index 0000000..ad2b077
--- /dev/null
+++ b/third_party/google-glog/libglog.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libglog
+Description: Google Log (glog) C++ logging framework
+Version: @VERSION@
+Libs: -L${libdir} -lglog
+Cflags: -I${includedir}
diff --git a/third_party/google-glog/m4/ac_have_attribute.m4 b/third_party/google-glog/m4/ac_have_attribute.m4
new file mode 100644
index 0000000..19f4021
--- /dev/null
+++ b/third_party/google-glog/m4/ac_have_attribute.m4
@@ -0,0 +1,16 @@
+AC_DEFUN([AX_C___ATTRIBUTE__], [
+  AC_MSG_CHECKING(for __attribute__)
+  AC_CACHE_VAL(ac_cv___attribute__, [
+    AC_TRY_COMPILE(
+      [#include <stdlib.h>
+       static void foo(void) __attribute__ ((unused));
+       void foo(void) { exit(1); }],
+      [],
+      ac_cv___attribute__=yes,
+      ac_cv___attribute__=no
+    )])
+  if test "$ac_cv___attribute__" = "yes"; then
+    AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+  fi
+  AC_MSG_RESULT($ac_cv___attribute__)
+])
diff --git a/third_party/google-glog/m4/ac_have_builtin_expect.m4 b/third_party/google-glog/m4/ac_have_builtin_expect.m4
new file mode 100644
index 0000000..e91b6fd
--- /dev/null
+++ b/third_party/google-glog/m4/ac_have_builtin_expect.m4
@@ -0,0 +1,14 @@
+AC_DEFUN([AX_C___BUILTIN_EXPECT], [
+  AC_MSG_CHECKING(for __builtin_expect)
+  AC_CACHE_VAL(ac_cv___builtin_expect, [
+    AC_TRY_COMPILE(
+      [int foo(void) { if (__builtin_expect(0, 0)) return 1; return 0; }],
+      [],
+      ac_cv___builtin_expect=yes,
+      ac_cv___builtin_expect=no
+    )])
+  if test "$ac_cv___builtin_expect" = "yes"; then
+    AC_DEFINE(HAVE___BUILTIN_EXPECT, 1, [define if your compiler has __builtin_expect])
+  fi
+  AC_MSG_RESULT($ac_cv___builtin_expect)
+])
diff --git a/third_party/google-glog/m4/ac_have_sync_val_compare_and_swap.m4 b/third_party/google-glog/m4/ac_have_sync_val_compare_and_swap.m4
new file mode 100644
index 0000000..88b027e
--- /dev/null
+++ b/third_party/google-glog/m4/ac_have_sync_val_compare_and_swap.m4
@@ -0,0 +1,14 @@
+AC_DEFUN([AX_C___SYNC_VAL_COMPARE_AND_SWAP], [
+  AC_MSG_CHECKING(for __sync_val_compare_and_swap)
+  AC_CACHE_VAL(ac_cv___sync_val_compare_and_swap, [
+    AC_TRY_LINK(
+      [],
+      [int a; if (__sync_val_compare_and_swap(&a, 0, 1)) return 1; return 0;],
+      ac_cv___sync_val_compare_and_swap=yes,
+      ac_cv___sync_val_compare_and_swap=no
+    )])
+  if test "$ac_cv___sync_val_compare_and_swap" = "yes"; then
+    AC_DEFINE(HAVE___SYNC_VAL_COMPARE_AND_SWAP, 1, [define if your compiler has __sync_val_compare_and_swap])
+  fi
+  AC_MSG_RESULT($ac_cv___sync_val_compare_and_swap)
+])
diff --git a/third_party/google-glog/m4/ac_rwlock.m4 b/third_party/google-glog/m4/ac_rwlock.m4
new file mode 100644
index 0000000..5065bcc
--- /dev/null
+++ b/third_party/google-glog/m4/ac_rwlock.m4
@@ -0,0 +1,31 @@
+# TODO(csilvers): it would be better to actually try to link against
+# -pthreads, to make sure it defines these methods, but that may be
+# too hard, since pthread support is really tricky.
+
+# Check for support for pthread_rwlock_init() etc.
+# These aren't posix, but are widely supported.  To get them on linux,
+# you need to define _XOPEN_SOURCE first, so this check assumes your
+# application does that.
+#
+# Note: OS X (as of 6/1/06) seems to support pthread_rwlock, but
+# doesn't define PTHREAD_RWLOCK_INITIALIZER.  Therefore, we don't test
+# that particularly macro.  It's probably best if you don't use that
+# macro in your code either.
+
+AC_DEFUN([AC_RWLOCK],
+[AC_CACHE_CHECK(support for pthread_rwlock_* functions,
+ac_cv_rwlock,
+[AC_LANG_SAVE
+ AC_LANG_C
+ AC_TRY_COMPILE([#define _XOPEN_SOURCE 500
+                 #include <pthread.h>],
+		[pthread_rwlock_t l; pthread_rwlock_init(&l, NULL);
+                 pthread_rwlock_rdlock(&l); 
+                 return 0;],
+                ac_cv_rwlock=yes, ac_cv_rwlock=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_rwlock" = yes; then
+  AC_DEFINE(HAVE_RWLOCK,1,[define if the compiler implements pthread_rwlock_*])
+fi
+])
diff --git a/third_party/google-glog/m4/acx_pthread.m4 b/third_party/google-glog/m4/acx_pthread.m4
new file mode 100644
index 0000000..2cf20de
--- /dev/null
+++ b/third_party/google-glog/m4/acx_pthread.m4
@@ -0,0 +1,363 @@
+# This was retrieved from
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
+# See also (perhaps for new versions?)
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
+#
+# We've rewritten the inconsistency check code (from avahi), to work
+# more broadly.  In particular, it no longer assumes ld accepts -zdefs.
+# This caused a restructing of the code, but the functionality has only
+# changed a little.
+
+dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl
+dnl @summary figure out how to build C programs using POSIX threads
+dnl
+dnl This macro figures out how to build C programs using POSIX threads.
+dnl It sets the PTHREAD_LIBS output variable to the threads library and
+dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
+dnl C compiler flags that are needed. (The user can also force certain
+dnl compiler flags/libs to be tested by setting these environment
+dnl variables.)
+dnl
+dnl Also sets PTHREAD_CC to any special C compiler that is needed for
+dnl multi-threaded programs (defaults to the value of CC otherwise).
+dnl (This is necessary on AIX to use the special cc_r compiler alias.)
+dnl
+dnl NOTE: You are assumed to not only compile your program with these
+dnl flags, but also link it with them as well. e.g. you should link
+dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
+dnl $LIBS
+dnl
+dnl If you are only building threads programs, you may wish to use
+dnl these variables in your default LIBS, CFLAGS, and CC:
+dnl
+dnl        LIBS="$PTHREAD_LIBS $LIBS"
+dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+dnl        CC="$PTHREAD_CC"
+dnl
+dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
+dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
+dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+dnl
+dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
+dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
+dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
+dnl default action will define HAVE_PTHREAD.
+dnl
+dnl Please let the authors know if this macro fails on any platform, or
+dnl if you have any other suggestions or comments. This macro was based
+dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
+dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
+dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
+dnl We are also grateful for the helpful feedback of numerous users.
+dnl
+dnl @category InstalledPackages
+dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
+dnl @version 2006-05-29
+dnl @license GPLWithACException
+dnl 
+dnl Checks for GCC shared/pthread inconsistency based on work by
+dnl Marcin Owsiany <marcin@owsiany.pl>
+
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_TRY_LINK([#include <pthread.h>],
+                    [pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+                    [acx_pthread_ok=yes])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	AC_MSG_CHECKING([for joinable pthread attribute])
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+                        [attr_name=$attr; break])
+	done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+	fi
+
+	# The next part tries to detect GCC inconsistency with -shared on some
+	# architectures and systems. The problem is that in certain
+	# configurations, when -shared is specified, GCC "forgets" to
+	# internally use various flags which are still necessary.
+	
+	#
+	# Prepare the flags
+	#
+	save_CFLAGS="$CFLAGS"
+	save_LIBS="$LIBS"
+	save_CC="$CC"
+	
+	# Try with the flags determined by the earlier checks.
+	#
+	# -Wl,-z,defs forces link-time symbol resolution, so that the
+	# linking checks with -shared actually have any value
+	#
+	# FIXME: -fPIC is required for -shared on many architectures,
+	# so we specify it here, but the right way would probably be to
+	# properly detect whether it is actually required.
+	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	CC="$PTHREAD_CC"
+	
+	# In order not to create several levels of indentation, we test
+	# the value of "$done" until we find the cure or run out of ideas.
+	done="no"
+	
+	# First, make sure the CFLAGS we added are actually accepted by our
+	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
+	# then we can't do this test.
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
+	   AC_TRY_LINK(,, , [done=yes])
+	
+	   if test "x$done" = xyes ; then
+	      AC_MSG_RESULT([no])
+	   else
+	      AC_MSG_RESULT([yes])
+	   fi
+	fi
+	
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	   
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	
+	#
+	# Linux gcc on some architectures such as mips/mipsel forgets
+	# about -lpthread
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lpthread fixes that])
+	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	#
+	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lc_r fixes that])
+	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	       [pthread_t th; pthread_join(th, 0);
+	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	        pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	       [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	if test x"$done" = xno; then
+	   # OK, we have run out of ideas
+	   AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
+	
+	   # so it's not safe to assume that we may use pthreads
+	   acx_pthread_ok=no
+	fi
+	
+	CFLAGS="$save_CFLAGS"
+	LIBS="$save_LIBS"
+	CC="$save_CC"
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        acx_pthread_ok=no
+        $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
diff --git a/third_party/google-glog/m4/google_namespace.m4 b/third_party/google-glog/m4/google_namespace.m4
new file mode 100644
index 0000000..79e0a6d
--- /dev/null
+++ b/third_party/google-glog/m4/google_namespace.m4
@@ -0,0 +1,36 @@
+# Allow users to override the namespace we define our application's classes in
+# Arg $1 is the default namespace to use if --enable-namespace isn't present.
+
+# In general, $1 should be 'google', so we put all our exported symbols in a
+# unique namespace that is not likely to conflict with anyone else.  However,
+# when it makes sense -- for instance, when publishing stl-like code -- you
+# may want to go with a different default, like 'std'.
+
+AC_DEFUN([AC_DEFINE_GOOGLE_NAMESPACE],
+  [google_namespace_default=[$1]
+   AC_ARG_ENABLE(namespace, [  --enable-namespace=FOO to define these Google
+                             classes in the FOO namespace. --disable-namespace
+                             to define them in the global namespace. Default
+                             is to define them in namespace $1.],
+                 [case "$enableval" in
+                    yes) google_namespace="$google_namespace_default" ;;
+                     no) google_namespace="" ;;
+                      *) google_namespace="$enableval" ;;
+                  esac],
+                 [google_namespace="$google_namespace_default"])
+   if test -n "$google_namespace"; then
+     ac_google_namespace="$google_namespace"
+     ac_google_start_namespace="namespace $google_namespace {"
+     ac_google_end_namespace="}"
+   else
+     ac_google_namespace=""
+     ac_google_start_namespace=""
+     ac_google_end_namespace=""
+   fi
+   AC_DEFINE_UNQUOTED(GOOGLE_NAMESPACE, $ac_google_namespace,
+                      Namespace for Google classes)
+   AC_DEFINE_UNQUOTED(_START_GOOGLE_NAMESPACE_, $ac_google_start_namespace,
+                      Puts following code inside the Google namespace)
+   AC_DEFINE_UNQUOTED(_END_GOOGLE_NAMESPACE_,  $ac_google_end_namespace,
+                      Stops putting the code inside the Google namespace)
+])
diff --git a/third_party/google-glog/m4/ltsugar.m4 b/third_party/google-glog/m4/ltsugar.m4
new file mode 100644
index 0000000..9000a05
--- /dev/null
+++ b/third_party/google-glog/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/third_party/google-glog/m4/lt~obsolete.m4 b/third_party/google-glog/m4/lt~obsolete.m4
new file mode 100644
index 0000000..c573da9
--- /dev/null
+++ b/third_party/google-glog/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
diff --git a/third_party/google-glog/m4/namespaces.m4 b/third_party/google-glog/m4/namespaces.m4
new file mode 100644
index 0000000..d78dbe4
--- /dev/null
+++ b/third_party/google-glog/m4/namespaces.m4
@@ -0,0 +1,15 @@
+# Checks whether the compiler implements namespaces
+AC_DEFUN([AC_CXX_NAMESPACES],
+ [AC_CACHE_CHECK(whether the compiler implements namespaces,
+                 ac_cv_cxx_namespaces,
+                 [AC_LANG_SAVE
+                  AC_LANG_CPLUSPLUS
+                  AC_TRY_COMPILE([namespace Outer {
+                                    namespace Inner { int i = 0; }}],
+                                 [using namespace Outer::Inner; return i;],
+                                 ac_cv_cxx_namespaces=yes,
+                                 ac_cv_cxx_namespaces=no)
+                  AC_LANG_RESTORE])
+  if test "$ac_cv_cxx_namespaces" = yes; then
+    AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces])
+  fi])
diff --git a/third_party/google-glog/m4/pc_from_ucontext.m4 b/third_party/google-glog/m4/pc_from_ucontext.m4
new file mode 100644
index 0000000..daffddb
--- /dev/null
+++ b/third_party/google-glog/m4/pc_from_ucontext.m4
@@ -0,0 +1,71 @@
+# We want to access the "PC" (Program Counter) register from a struct
+# ucontext.  Every system has its own way of doing that.  We try all the
+# possibilities we know about.  Note REG_PC should come first (REG_RIP
+# is also defined on solaris, but does the wrong thing).
+
+# OpenBSD doesn't have ucontext.h, but we can get PC from ucontext_t
+# by using signal.h.
+
+# The first argument of AC_PC_FROM_UCONTEXT will be invoked when we
+# cannot find a way to obtain PC from ucontext.
+
+AC_DEFUN([AC_PC_FROM_UCONTEXT],
+  [AC_CHECK_HEADERS(ucontext.h)
+   AC_CHECK_HEADERS(sys/ucontext.h)       # ucontext on OS X 10.6 (at least)
+   AC_MSG_CHECKING([how to access the program counter from a struct ucontext])
+   pc_fields="           uc_mcontext.gregs[[REG_PC]]"  # Solaris x86 (32 + 64 bit)
+   pc_fields="$pc_fields uc_mcontext.gregs[[REG_EIP]]" # Linux (i386)
+   pc_fields="$pc_fields uc_mcontext.gregs[[REG_RIP]]" # Linux (x86_64)
+   pc_fields="$pc_fields uc_mcontext.sc_ip"            # Linux (ia64)
+   pc_fields="$pc_fields uc_mcontext.uc_regs->gregs[[PT_NIP]]" # Linux (ppc)
+   pc_fields="$pc_fields uc_mcontext.gregs[[R15]]"     # Linux (arm old [untested])
+   pc_fields="$pc_fields uc_mcontext.arm_pc"           # Linux (arm new [untested])
+   pc_fields="$pc_fields uc_mcontext.mc_eip"           # FreeBSD (i386)
+   pc_fields="$pc_fields uc_mcontext.mc_rip"           # FreeBSD (x86_64 [untested])
+   pc_fields="$pc_fields uc_mcontext.__gregs[[_REG_EIP]]"  # NetBSD (i386)
+   pc_fields="$pc_fields uc_mcontext.__gregs[[_REG_RIP]]"  # NetBSD (x86_64)
+   pc_fields="$pc_fields uc_mcontext->ss.eip"          # OS X (i386, <=10.4)
+   pc_fields="$pc_fields uc_mcontext->__ss.__eip"      # OS X (i386, >=10.5)
+   pc_fields="$pc_fields uc_mcontext->ss.rip"          # OS X (x86_64)
+   pc_fields="$pc_fields uc_mcontext->__ss.__rip"      # OS X (>=10.5 [untested])
+   pc_fields="$pc_fields uc_mcontext->ss.srr0"         # OS X (ppc, ppc64 [untested])
+   pc_fields="$pc_fields uc_mcontext->__ss.__srr0"     # OS X (>=10.5 [untested])
+   pc_field_found=false
+   for pc_field in $pc_fields; do
+     if ! $pc_field_found; then
+       if test "x$ac_cv_header_sys_ucontext_h" = xyes; then
+         AC_TRY_COMPILE([#define _GNU_SOURCE 1
+                         #include <sys/ucontext.h>],
+                        [ucontext_t u; return u.$pc_field == 0;],
+                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
+                                           How to access the PC from a struct ucontext)
+                        AC_MSG_RESULT([$pc_field])
+                        pc_field_found=true)
+       else
+         AC_TRY_COMPILE([#define _GNU_SOURCE 1
+                         #include <ucontext.h>],
+                        [ucontext_t u; return u.$pc_field == 0;],
+                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
+                                           How to access the PC from a struct ucontext)
+                        AC_MSG_RESULT([$pc_field])
+                        pc_field_found=true)
+       fi
+     fi
+   done
+   if ! $pc_field_found; then
+     pc_fields="           sc_eip"  # OpenBSD (i386)
+     pc_fields="$pc_fields sc_rip"  # OpenBSD (x86_64)
+     for pc_field in $pc_fields; do
+       if ! $pc_field_found; then
+         AC_TRY_COMPILE([#include <signal.h>],
+                        [ucontext_t u; return u.$pc_field == 0;],
+                        AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
+                                           How to access the PC from a struct ucontext)
+                        AC_MSG_RESULT([$pc_field])
+                        pc_field_found=true)
+       fi
+     done
+   fi
+   if ! $pc_field_found; then
+     [$1]
+   fi])
diff --git a/third_party/google-glog/m4/stl_namespace.m4 b/third_party/google-glog/m4/stl_namespace.m4
new file mode 100644
index 0000000..989ad80
--- /dev/null
+++ b/third_party/google-glog/m4/stl_namespace.m4
@@ -0,0 +1,25 @@
+# We check what namespace stl code like vector expects to be executed in
+
+AC_DEFUN([AC_CXX_STL_NAMESPACE],
+  [AC_CACHE_CHECK(
+      what namespace STL code is in,
+      ac_cv_cxx_stl_namespace,
+      [AC_REQUIRE([AC_CXX_NAMESPACES])
+      AC_LANG_SAVE
+      AC_LANG_CPLUSPLUS
+      AC_TRY_COMPILE([#include <vector>],
+                     [vector<int> t; return 0;],
+                     ac_cv_cxx_stl_namespace=none)
+      AC_TRY_COMPILE([#include <vector>],
+                     [std::vector<int> t; return 0;],
+                     ac_cv_cxx_stl_namespace=std)
+      AC_LANG_RESTORE])
+   if test "$ac_cv_cxx_stl_namespace" = none; then
+      AC_DEFINE(STL_NAMESPACE,,
+                [the namespace where STL code like vector<> is defined])
+   fi
+   if test "$ac_cv_cxx_stl_namespace" = std; then
+      AC_DEFINE(STL_NAMESPACE,std,
+                [the namespace where STL code like vector<> is defined])
+   fi
+])
diff --git a/third_party/google-glog/m4/using_operator.m4 b/third_party/google-glog/m4/using_operator.m4
new file mode 100644
index 0000000..95a9951
--- /dev/null
+++ b/third_party/google-glog/m4/using_operator.m4
@@ -0,0 +1,15 @@
+AC_DEFUN([AC_CXX_USING_OPERATOR],
+  [AC_CACHE_CHECK(
+      whether compiler supports using ::operator<<,
+      ac_cv_cxx_using_operator,
+      [AC_LANG_SAVE
+       AC_LANG_CPLUSPLUS
+       AC_TRY_COMPILE([#include <iostream>
+                       std::ostream& operator<<(std::ostream&, struct s);],
+                      [using ::operator<<; return 0;],
+                      ac_cv_cxx_using_operator=1,
+		      ac_cv_cxx_using_operator=0)
+      AC_LANG_RESTORE])
+  if test "$ac_cv_cxx_using_operator" = 1; then
+    AC_DEFINE(HAVE_USING_OPERATOR, 1, [define if the compiler supports using expression for operator])
+  fi])
diff --git a/third_party/google-glog/packages/deb.sh b/third_party/google-glog/packages/deb.sh
new file mode 100755
index 0000000..a1cdf32
--- /dev/null
+++ b/third_party/google-glog/packages/deb.sh
@@ -0,0 +1,73 @@
+#!/bin/bash -e
+
+# This takes one commandline argument, the name of the package.  If no
+# name is given, then we'll end up just using the name associated with
+# an arbitrary .tar.gz file in the rootdir.  That's fine: there's probably
+# only one.
+#
+# Run this from the 'packages' directory, just under rootdir
+
+## Set LIB to lib if exporting a library, empty-string else
+LIB=
+#LIB=lib
+
+PACKAGE="$1"
+VERSION="$2"
+
+# We can only build Debian packages, if the Debian build tools are installed
+if [ \! -x /usr/bin/debuild ]; then
+  echo "Cannot find /usr/bin/debuild. Not building Debian packages." 1>&2
+  exit 0
+fi
+
+# Double-check we're in the packages directory, just under rootdir
+if [ \! -r ../Makefile -a \! -r ../INSTALL ]; then
+  echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
+  echo "Also, you must run \"make dist\" before running this script." 1>&2
+  exit 0
+fi
+
+# Find the top directory for this package
+topdir="${PWD%/*}"
+
+# Find the tar archive built by "make dist"
+archive="$PACKAGE-$VERSION"
+if [ -z "${archive}" ]; then
+  echo "Cannot find ../$PACKAGE*.tar.gz. Run \"make dist\" first." 1>&2
+  exit 0
+fi
+
+# Create a pristine directory for building the Debian package files
+trap 'rm -rf '`pwd`/tmp'; exit $?' EXIT SIGHUP SIGINT SIGTERM
+
+rm -rf tmp
+mkdir -p tmp
+cd tmp
+
+package="google-glog_$VERSION"
+
+# Debian has very specific requirements about the naming of build
+# directories, and tar archives. It also wants to write all generated
+# packages to the parent of the source directory. We accommodate these
+# requirements by building directly from the tar file.
+ln -s "${topdir}/${archive}.tar.gz" "${LIB}${package}.orig.tar.gz"
+tar zfx "${LIB}${package}.orig.tar.gz"
+mv "${archive}" "${LIB}${package}"
+cd "${LIB}${package}"
+# This is one of those 'specific requirements': where the deb control files live
+cp -a "packages/deb" "debian"
+
+# Now, we can call Debian's standard build tool
+debuild -uc -us
+cd ../..                            # get back to the original top-level dir
+
+# We'll put the result in a subdirectory that's named after the OS version
+# we've made this .deb file for.
+destdir="debian-$(cat /etc/debian_version 2>/dev/null || echo UNKNOWN)"
+
+rm -rf "$destdir"
+mkdir -p "$destdir"
+mv $(find tmp -mindepth 1 -maxdepth 1 -type f) "$destdir"
+
+echo
+echo "The Debian package files are located in $PWD/$destdir"
diff --git a/third_party/google-glog/packages/deb/README b/third_party/google-glog/packages/deb/README
new file mode 100644
index 0000000..57becfd
--- /dev/null
+++ b/third_party/google-glog/packages/deb/README
@@ -0,0 +1,7 @@
+The list of files here isn't complete.  For a step-by-step guide on
+how to set this package up correctly, check out
+    http://www.debian.org/doc/maint-guide/
+
+Most of the files that are in this directory are boilerplate.
+However, you may need to change the list of binary-arch dependencies
+in 'rules'.
diff --git a/third_party/google-glog/packages/deb/changelog b/third_party/google-glog/packages/deb/changelog
new file mode 100644
index 0000000..261cfd5
--- /dev/null
+++ b/third_party/google-glog/packages/deb/changelog
@@ -0,0 +1,65 @@
+google-glog (0.3.5-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Tue, 09 May 2017 16:22:12 +0900
+
+google-glog (0.3.4-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Tue, 10 Mar 2015 12:02:20 +0900
+
+google-glog (0.3.3-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Fri, 01 Feb 2012 14:54:14 +0900
+
+google-glog (0.3.2-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Thu, 12 Jan 2012 17:36:14 +0900
+
+google-glog (0.3.1-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Tue, 15 Jun 2010 13:50:47 +0900
+
+google-glog (0.3-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Thu, 30 Jul 2009 21:31:35 +0900
+
+google-glog (0.2.1-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Fri, 10 Apr 2009 15:24:17 +0900
+
+google-glog (0.2-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Fri, 23 Jan 2009 03:14:29 +0900
+
+google-glog (0.1.2-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Tue, 18 Nov 2008 20:37:00 +0900
+
+google-glog (0.1.1-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Google Inc. <opensource@google.com>  Wed, 15 Oct 2008 20:38:19 +0900
+
+google-glog (0.1-1) unstable; urgency=low
+
+  * Initial release.
+
+ -- Google Inc. <opensource@google.com>  Sat, 10 May 2008 12:31:10 +0900
diff --git a/third_party/google-glog/packages/deb/compat b/third_party/google-glog/packages/deb/compat
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/third_party/google-glog/packages/deb/compat
@@ -0,0 +1 @@
+4
diff --git a/third_party/google-glog/packages/deb/control b/third_party/google-glog/packages/deb/control
new file mode 100644
index 0000000..110a72c
--- /dev/null
+++ b/third_party/google-glog/packages/deb/control
@@ -0,0 +1,23 @@
+Source: google-glog
+Priority: optional
+Maintainer: Google Inc. <opensource@google.com>
+Build-Depends: debhelper (>= 4.0.0), binutils
+Standards-Version: 3.6.1
+
+Package: libgoogle-glog-dev
+Section: libdevel
+Architecture: any
+Depends: libgoogle-glog0 (= ${Source-Version})
+Description:  a library that implements application-level logging.
+ This library provides logging APIs based on C++-style streams and
+ various helper macros.  The devel package contains static and debug
+ libraries and header files for developing applications that use the
+ google-glog package.
+
+Package: libgoogle-glog0
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}
+Description:  a library that implements application-level logging.
+ This library provides logging APIs based on C++-style streams and
+ various helper macros.
diff --git a/third_party/google-glog/packages/deb/copyright b/third_party/google-glog/packages/deb/copyright
new file mode 100644
index 0000000..b2ce8e8
--- /dev/null
+++ b/third_party/google-glog/packages/deb/copyright
@@ -0,0 +1,35 @@
+This package was debianized by Google Inc. <opensource@google.com> on
+13 June 2008.
+
+It was downloaded from https://github.com/google/glog
+
+Upstream Author: opensource@google.com
+
+Copyright (c) 2008, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/google-glog/packages/deb/docs b/third_party/google-glog/packages/deb/docs
new file mode 100644
index 0000000..6da25d4
--- /dev/null
+++ b/third_party/google-glog/packages/deb/docs
@@ -0,0 +1,7 @@
+AUTHORS
+COPYING
+ChangeLog
+INSTALL
+README.md
+doc/designstyle.css
+doc/glog.html
diff --git a/third_party/google-glog/packages/deb/libgoogle-glog-dev.dirs b/third_party/google-glog/packages/deb/libgoogle-glog-dev.dirs
new file mode 100644
index 0000000..bddfbf5
--- /dev/null
+++ b/third_party/google-glog/packages/deb/libgoogle-glog-dev.dirs
@@ -0,0 +1,4 @@
+usr/lib
+usr/lib/pkgconfig
+usr/include
+usr/include/glog
diff --git a/third_party/google-glog/packages/deb/libgoogle-glog-dev.install b/third_party/google-glog/packages/deb/libgoogle-glog-dev.install
new file mode 100644
index 0000000..9c61e86
--- /dev/null
+++ b/third_party/google-glog/packages/deb/libgoogle-glog-dev.install
@@ -0,0 +1,10 @@
+usr/include/glog/*
+usr/lib/lib*.so
+usr/lib/lib*.a
+usr/lib/*.la
+usr/lib/pkgconfig/*
+debian/tmp/usr/include/glog/*
+debian/tmp/usr/lib/lib*.so
+debian/tmp/usr/lib/lib*.a
+debian/tmp/usr/lib/*.la
+debian/tmp/usr/lib/pkgconfig/*
diff --git a/third_party/google-glog/packages/deb/libgoogle-glog0.dirs b/third_party/google-glog/packages/deb/libgoogle-glog0.dirs
new file mode 100644
index 0000000..6845771
--- /dev/null
+++ b/third_party/google-glog/packages/deb/libgoogle-glog0.dirs
@@ -0,0 +1 @@
+usr/lib
diff --git a/third_party/google-glog/packages/deb/libgoogle-glog0.install b/third_party/google-glog/packages/deb/libgoogle-glog0.install
new file mode 100644
index 0000000..704ea87
--- /dev/null
+++ b/third_party/google-glog/packages/deb/libgoogle-glog0.install
@@ -0,0 +1,2 @@
+usr/lib/lib*.so.*
+debian/tmp/usr/lib/lib*.so.*
diff --git a/third_party/google-glog/packages/deb/rules b/third_party/google-glog/packages/deb/rules
new file mode 100755
index 0000000..f520bef
--- /dev/null
+++ b/third_party/google-glog/packages/deb/rules
@@ -0,0 +1,117 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+	CFLAGS += -O0
+else
+	CFLAGS += -O2
+endif
+ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+	INSTALL_PROGRAM += -s
+endif
+
+# shared library versions, option 1
+#version=2.0.5
+#major=2
+# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
+version=`ls src/.libs/lib*.so.* | \
+ awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
+major=`ls src/.libs/lib*.so.* | \
+ awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
+
+config.status: configure
+	dh_testdir
+	# Add here commands to configure the package.
+	CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
+
+
+build: build-stamp
+build-stamp:  config.status
+	dh_testdir
+
+	# Add here commands to compile the package.
+	$(MAKE)
+
+	touch build-stamp
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp 
+
+	# Add here commands to clean up after the build process.
+	-$(MAKE) distclean
+ifneq "$(wildcard /usr/share/misc/config.sub)" ""
+	cp -f /usr/share/misc/config.sub config.sub
+endif
+ifneq "$(wildcard /usr/share/misc/config.guess)" ""
+	cp -f /usr/share/misc/config.guess config.guess
+endif
+
+
+	dh_clean 
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k 
+	dh_installdirs
+
+	# Add here commands to install the package into debian/tmp
+	$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs ChangeLog
+	dh_installdocs
+	dh_installexamples
+	dh_install --sourcedir=debian/tmp
+#	dh_installmenu
+#	dh_installdebconf	
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+#	dh_installinit
+#	dh_installcron
+#	dh_installinfo
+	dh_installman
+	dh_link
+	dh_strip
+	dh_compress
+	dh_fixperms
+#	dh_perl
+#	dh_python
+	dh_makeshlibs
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install 
diff --git a/third_party/google-glog/packages/rpm.sh b/third_party/google-glog/packages/rpm.sh
new file mode 100755
index 0000000..e5649a2
--- /dev/null
+++ b/third_party/google-glog/packages/rpm.sh
@@ -0,0 +1,75 @@
+#!/bin/sh -e
+
+# Run this from the 'packages' directory, just under rootdir
+
+# We can only build rpm packages, if the rpm build tools are installed
+if [ \! -x /usr/bin/rpmbuild ]
+then
+  echo "Cannot find /usr/bin/rpmbuild. Not building an rpm." 1>&2
+  exit 0
+fi
+
+# Check the commandline flags
+PACKAGE="$1"
+VERSION="$2"
+fullname="${PACKAGE}-${VERSION}"
+archive=../$fullname.tar.gz
+
+if [ -z "$1" -o -z "$2" ]
+then
+  echo "Usage: $0 <package name> <package version>" 1>&2
+  exit 0
+fi
+
+# Double-check we're in the packages directory, just under rootdir
+if [ \! -r ../Makefile -a \! -r ../INSTALL ]
+then
+  echo "Must run $0 in the 'packages' directory, under the root directory." 1>&2
+  echo "Also, you must run \"make dist\" before running this script." 1>&2
+  exit 0
+fi
+
+if [ \! -r "$archive" ]
+then
+  echo "Cannot find $archive. Run \"make dist\" first." 1>&2
+  exit 0
+fi
+
+# Create the directory where the input lives, and where the output should live
+RPM_SOURCE_DIR="/tmp/rpmsource-$fullname"
+RPM_BUILD_DIR="/tmp/rpmbuild-$fullname"
+
+trap 'rm -rf $RPM_SOURCE_DIR $RPM_BUILD_DIR; exit $?' EXIT SIGHUP SIGINT SIGTERM
+
+rm -rf "$RPM_SOURCE_DIR" "$RPM_BUILD_DIR"
+mkdir "$RPM_SOURCE_DIR"
+mkdir "$RPM_BUILD_DIR"
+
+cp "$archive" "$RPM_SOURCE_DIR"/v"$VERSION".tar.gz
+
+rpmbuild -bb rpm/rpm.spec \
+  --define "NAME $PACKAGE" \
+  --define "VERSION $VERSION" \
+  --define "_sourcedir $RPM_SOURCE_DIR" \
+  --define "_builddir $RPM_BUILD_DIR" \
+  --define "_rpmdir $RPM_SOURCE_DIR"
+
+# We put the output in a directory based on what system we've built for
+destdir=rpm-unknown
+if [ -r /etc/issue ]
+then
+   grep "Red Hat.*release 7" /etc/issue >/dev/null 2>&1 && destdir=rh7
+   grep "Red Hat.*release 8" /etc/issue >/dev/null 2>&1 && destdir=rh8
+   grep "Red Hat.*release 9" /etc/issue >/dev/null 2>&1 && destdir=rh9
+   if grep Fedora /etc/issue >/dev/null; then 
+	destdir=fc`grep Fedora /etc/issue | cut -d' ' -f 4`;
+   fi
+fi
+
+rm -rf "$destdir"
+mkdir -p "$destdir"
+# We want to get not only the main package but devel etc, hence the middle *
+mv "$RPM_SOURCE_DIR"/*/"${PACKAGE}"-*"${VERSION}"*.rpm "$destdir"
+
+echo
+echo "The rpm package file(s) are located in $PWD/$destdir"
diff --git a/third_party/google-glog/packages/rpm/rpm.spec b/third_party/google-glog/packages/rpm/rpm.spec
new file mode 100644
index 0000000..24ef134
--- /dev/null
+++ b/third_party/google-glog/packages/rpm/rpm.spec
@@ -0,0 +1,72 @@
+%define	RELEASE	1
+%define rel     %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
+%define	prefix	/usr
+
+Name: %NAME
+Summary: A C++ application logging library
+Version: %VERSION
+Release: %rel
+Group: Development/Libraries
+URL: http://github.com/google/glog
+License: BSD
+Vendor: Google
+Packager: Google Inc. <opensource@google.com>
+Source: https://github.com/google/glog/archive/v%{VERSION}.tar.gz
+Distribution: Redhat 7 and above.
+Buildroot: %{_tmppath}/%{name}-root
+Prefix: %prefix
+
+%description
+The %name package contains a library that implements application-level
+logging.  This library provides logging APIs based on C++-style
+streams and various helper macros.
+
+%package devel
+Summary: A C++ application logging library
+Group: Development/Libraries
+Requires: %{NAME} = %{VERSION}
+
+%description devel
+The %name-devel package contains static and debug libraries and header
+files for developing applications that use the %name package.
+
+%changelog
+    * Wed Mar 26 2008 <opensource@google.com>
+    - First draft
+
+%prep
+%setup
+
+%build
+./configure
+make prefix=%prefix
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make prefix=$RPM_BUILD_ROOT%{prefix} install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+
+## Mark all installed files within /usr/share/doc/{package name} as
+## documentation.  This depends on the following two lines appearing in
+## Makefile.am:
+##     docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
+##     dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL README.md
+%docdir %{prefix}/share/doc/%{NAME}-%{VERSION}
+%{prefix}/share/doc/%{NAME}-%{VERSION}/*
+
+%{prefix}/lib/libglog.so.0
+%{prefix}/lib/libglog.so.0.0.0
+
+%files devel
+%defattr(-,root,root)
+
+%{prefix}/include/glog
+%{prefix}/lib/libglog.a
+%{prefix}/lib/libglog.la
+%{prefix}/lib/libglog.so
+%{prefix}/lib/pkgconfig/libglog.pc
diff --git a/third_party/google-glog/src/base/commandlineflags.h b/third_party/google-glog/src/base/commandlineflags.h
new file mode 100644
index 0000000..c8d5089
--- /dev/null
+++ b/third_party/google-glog/src/base/commandlineflags.h
@@ -0,0 +1,133 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// 
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// This file is a compatibility layer that defines Google's version of
+// command line flags that are used for configuration.
+//
+// We put flags into their own namespace.  It is purposefully
+// named in an opaque way that people should have trouble typing
+// directly.  The idea is that DEFINE puts the flag in the weird
+// namespace, and DECLARE imports the flag from there into the
+// current namespace.  The net result is to force people to use
+// DECLARE to get access to a flag, rather than saying
+//   extern bool FLAGS_logtostderr;
+// or some such instead.  We want this so we can put extra
+// functionality (like sanity-checking) in DECLARE if we want,
+// and make sure it is picked up everywhere.
+//
+// We also put the type of the variable in the namespace, so that
+// people can't DECLARE_int32 something that they DEFINE_bool'd
+// elsewhere.
+#ifndef BASE_COMMANDLINEFLAGS_H__
+#define BASE_COMMANDLINEFLAGS_H__
+
+#include "config.h"
+#include <string>
+#include <string.h>               // for memchr
+#include <stdlib.h>               // for getenv
+
+#ifdef HAVE_LIB_GFLAGS
+
+#include <gflags/gflags.h>
+
+#else
+
+#include "glog/logging.h"
+
+#define DECLARE_VARIABLE(type, shorttype, name, tn)                     \
+  namespace fL##shorttype {                                             \
+    extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name;                      \
+  }                                                                     \
+  using fL##shorttype::FLAGS_##name
+#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn)      \
+  namespace fL##shorttype {                                             \
+    GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value);                      \
+    char FLAGS_no##name;                                                \
+  }                                                                     \
+  using fL##shorttype::FLAGS_##name
+
+// bool specialization
+#define DECLARE_bool(name) \
+  DECLARE_VARIABLE(bool, B, name, bool)
+#define DEFINE_bool(name, value, meaning) \
+  DEFINE_VARIABLE(bool, B, name, value, meaning, bool)
+
+// int32 specialization
+#define DECLARE_int32(name) \
+  DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, int32)
+#define DEFINE_int32(name, value, meaning) \
+  DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, value, meaning, int32)
+
+// Special case for string, because we have to specify the namespace
+// std::string, which doesn't play nicely with our FLAG__namespace hackery.
+#define DECLARE_string(name)                                            \
+  namespace fLS {                                                       \
+    extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name;              \
+  }                                                                     \
+  using fLS::FLAGS_##name
+#define DEFINE_string(name, value, meaning)                             \
+  namespace fLS {                                                       \
+    std::string FLAGS_##name##_buf(value);                              \
+    GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name = FLAGS_##name##_buf; \
+    char FLAGS_no##name;                                                \
+  }                                                                     \
+  using fLS::FLAGS_##name
+
+#endif  // HAVE_LIB_GFLAGS
+
+// Define GLOG_DEFINE_* using DEFINE_* . By using these macros, we
+// have GLOG_* environ variables even if we have gflags installed.
+//
+// If both an environment variable and a flag are specified, the value
+// specified by a flag wins. E.g., if GLOG_v=0 and --v=1, the
+// verbosity will be 1, not 0.
+
+#define GLOG_DEFINE_bool(name, value, meaning) \
+  DEFINE_bool(name, EnvToBool("GLOG_" #name, value), meaning)
+
+#define GLOG_DEFINE_int32(name, value, meaning) \
+  DEFINE_int32(name, EnvToInt("GLOG_" #name, value), meaning)
+
+#define GLOG_DEFINE_string(name, value, meaning) \
+  DEFINE_string(name, EnvToString("GLOG_" #name, value), meaning)
+
+// These macros (could be functions, but I don't want to bother with a .cc
+// file), make it easier to initialize flags from the environment.
+
+#define EnvToString(envname, dflt)   \
+  (!getenv(envname) ? (dflt) : getenv(envname))
+
+#define EnvToBool(envname, dflt)   \
+  (!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL)
+
+#define EnvToInt(envname, dflt)  \
+  (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10))
+
+#endif  // BASE_COMMANDLINEFLAGS_H__
diff --git a/third_party/google-glog/src/base/googleinit.h b/third_party/google-glog/src/base/googleinit.h
new file mode 100644
index 0000000..5a8b515
--- /dev/null
+++ b/third_party/google-glog/src/base/googleinit.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// 
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Jacob Hoffman-Andrews
+
+#ifndef _GOOGLEINIT_H
+#define _GOOGLEINIT_H
+
+class GoogleInitializer {
+ public:
+  typedef void (*void_function)(void);
+  GoogleInitializer(const char*, void_function f) {
+    f();
+  }
+};
+
+#define REGISTER_MODULE_INITIALIZER(name, body)                 \
+  namespace {                                                   \
+    static void google_init_module_##name () { body; }          \
+    GoogleInitializer google_initializer_module_##name(#name,   \
+            google_init_module_##name);                         \
+  }
+
+#endif /* _GOOGLEINIT_H */
diff --git a/third_party/google-glog/src/base/mutex.h b/third_party/google-glog/src/base/mutex.h
new file mode 100644
index 0000000..ced2b99
--- /dev/null
+++ b/third_party/google-glog/src/base/mutex.h
@@ -0,0 +1,333 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// 
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+// ---
+// Author: Craig Silverstein.
+//
+// A simple mutex wrapper, supporting locks and read-write locks.
+// You should assume the locks are *not* re-entrant.
+//
+// To use: you should define the following macros in your configure.ac:
+//   ACX_PTHREAD
+//   AC_RWLOCK
+// The latter is defined in ../autoconf.
+//
+// This class is meant to be internal-only and should be wrapped by an
+// internal namespace.  Before you use this module, please give the
+// name of your internal namespace for this module.  Or, if you want
+// to expose it, you'll want to move it to the Google namespace.  We
+// cannot put this class in global namespace because there can be some
+// problems when we have multiple versions of Mutex in each shared object.
+//
+// NOTE: by default, we have #ifdef'ed out the TryLock() method.
+//       This is for two reasons:
+// 1) TryLock() under Windows is a bit annoying (it requires a
+//    #define to be defined very early).
+// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG
+//    mode.
+// If you need TryLock(), and either these two caveats are not a
+// problem for you, or you're willing to work around them, then
+// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs
+// in the code below.
+//
+// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy:
+//    http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html
+// Because of that, we might as well use windows locks for
+// cygwin.  They seem to be more reliable than the cygwin pthreads layer.
+//
+// TRICKY IMPLEMENTATION NOTE:
+// This class is designed to be safe to use during
+// dynamic-initialization -- that is, by global constructors that are
+// run before main() starts.  The issue in this case is that
+// dynamic-initialization happens in an unpredictable order, and it
+// could be that someone else's dynamic initializer could call a
+// function that tries to acquire this mutex -- but that all happens
+// before this mutex's constructor has run.  (This can happen even if
+// the mutex and the function that uses the mutex are in the same .cc
+// file.)  Basically, because Mutex does non-trivial work in its
+// constructor, it's not, in the naive implementation, safe to use
+// before dynamic initialization has run on it.
+//
+// The solution used here is to pair the actual mutex primitive with a
+// bool that is set to true when the mutex is dynamically initialized.
+// (Before that it's false.)  Then we modify all mutex routines to
+// look at the bool, and not try to lock/unlock until the bool makes
+// it to true (which happens after the Mutex constructor has run.)
+//
+// This works because before main() starts -- particularly, during
+// dynamic initialization -- there are no threads, so a) it's ok that
+// the mutex operations are a no-op, since we don't need locking then
+// anyway; and b) we can be quite confident our bool won't change
+// state between a call to Lock() and a call to Unlock() (that would
+// require a global constructor in one translation unit to call Lock()
+// and another global constructor in another translation unit to call
+// Unlock() later, which is pretty perverse).
+//
+// That said, it's tricky, and can conceivably fail; it's safest to
+// avoid trying to acquire a mutex in a global constructor, if you
+// can.  One way it can fail is that a really smart compiler might
+// initialize the bool to true at static-initialization time (too
+// early) rather than at dynamic-initialization time.  To discourage
+// that, we set is_safe_ to true in code (not the constructor
+// colon-initializer) and set it to true via a function that always
+// evaluates to true, but that the compiler can't know always
+// evaluates to true.  This should be good enough.
+
+#ifndef GOOGLE_MUTEX_H_
+#define GOOGLE_MUTEX_H_
+
+#include "config.h"           // to figure out pthreads support
+
+#if defined(NO_THREADS)
+  typedef int MutexType;      // to keep a lock-count
+#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+# ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN  // We only need minimal includes
+# endif
+# ifdef GMUTEX_TRYLOCK
+  // We need Windows NT or later for TryEnterCriticalSection().  If you
+  // don't need that functionality, you can remove these _WIN32_WINNT
+  // lines, and change TryLock() to assert(0) or something.
+#   ifndef _WIN32_WINNT
+#     define _WIN32_WINNT 0x0400
+#   endif
+# endif
+// To avoid macro definition of ERROR.
+# ifndef NOGDI
+#  define NOGDI
+# endif
+// To avoid macro definition of min/max.
+# ifndef NOMINMAX
+#  define NOMINMAX
+# endif
+# include <windows.h>
+  typedef CRITICAL_SECTION MutexType;
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+  // Needed for pthread_rwlock_*.  If it causes problems, you could take it
+  // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it
+  // *does* cause problems for FreeBSD, or MacOSX, but isn't needed
+  // for locking there.)
+# ifdef __linux__
+#   ifndef _XOPEN_SOURCE  // Some other header might have already set it for us.
+#     define _XOPEN_SOURCE 500  // may be needed to get the rwlock calls
+#   endif
+# endif
+# include <pthread.h>
+  typedef pthread_rwlock_t MutexType;
+#elif defined(HAVE_PTHREAD)
+# include <pthread.h>
+  typedef pthread_mutex_t MutexType;
+#else
+# error Need to implement mutex.h for your architecture, or #define NO_THREADS
+#endif
+
+// We need to include these header files after defining _XOPEN_SOURCE
+// as they may define the _XOPEN_SOURCE macro.
+#include <assert.h>
+#include <stdlib.h>      // for abort()
+
+#define MUTEX_NAMESPACE glog_internal_namespace_
+
+namespace MUTEX_NAMESPACE {
+
+class Mutex {
+ public:
+  // Create a Mutex that is not held by anybody.  This constructor is
+  // typically used for Mutexes allocated on the heap or the stack.
+  // See below for a recommendation for constructing global Mutex
+  // objects.
+  inline Mutex();
+
+  // Destructor
+  inline ~Mutex();
+
+  inline void Lock();    // Block if needed until free then acquire exclusively
+  inline void Unlock();  // Release a lock acquired via Lock()
+#ifdef GMUTEX_TRYLOCK
+  inline bool TryLock(); // If free, Lock() and return true, else return false
+#endif
+  // Note that on systems that don't support read-write locks, these may
+  // be implemented as synonyms to Lock() and Unlock().  So you can use
+  // these for efficiency, but don't use them anyplace where being able
+  // to do shared reads is necessary to avoid deadlock.
+  inline void ReaderLock();   // Block until free or shared then acquire a share
+  inline void ReaderUnlock(); // Release a read share of this Mutex
+  inline void WriterLock() { Lock(); }     // Acquire an exclusive lock
+  inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock()
+
+  // TODO(hamaji): Do nothing, implement correctly.
+  inline void AssertHeld() {}
+
+ private:
+  MutexType mutex_;
+  // We want to make sure that the compiler sets is_safe_ to true only
+  // when we tell it to, and never makes assumptions is_safe_ is
+  // always true.  volatile is the most reliable way to do that.
+  volatile bool is_safe_;
+
+  inline void SetIsSafe() { is_safe_ = true; }
+
+  // Catch the error of writing Mutex when intending MutexLock.
+  Mutex(Mutex* /*ignored*/) {}
+  // Disallow "evil" constructors
+  Mutex(const Mutex&);
+  void operator=(const Mutex&);
+};
+
+// Now the implementation of Mutex for various systems
+#if defined(NO_THREADS)
+
+// When we don't have threads, we can be either reading or writing,
+// but not both.  We can have lots of readers at once (in no-threads
+// mode, that's most likely to happen in recursive function calls),
+// but only one writer.  We represent this by having mutex_ be -1 when
+// writing and a number > 0 when reading (and 0 when no lock is held).
+//
+// In debug mode, we assert these invariants, while in non-debug mode
+// we do nothing, for efficiency.  That's why everything is in an
+// assert.
+
+Mutex::Mutex() : mutex_(0) { }
+Mutex::~Mutex()            { assert(mutex_ == 0); }
+void Mutex::Lock()         { assert(--mutex_ == -1); }
+void Mutex::Unlock()       { assert(mutex_++ == -1); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock()      { if (mutex_) return false; Lock(); return true; }
+#endif
+void Mutex::ReaderLock()   { assert(++mutex_ > 0); }
+void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
+
+#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+
+Mutex::Mutex()             { InitializeCriticalSection(&mutex_); SetIsSafe(); }
+Mutex::~Mutex()            { DeleteCriticalSection(&mutex_); }
+void Mutex::Lock()         { if (is_safe_) EnterCriticalSection(&mutex_); }
+void Mutex::Unlock()       { if (is_safe_) LeaveCriticalSection(&mutex_); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock()      { return is_safe_ ?
+                                 TryEnterCriticalSection(&mutex_) != 0 : true; }
+#endif
+void Mutex::ReaderLock()   { Lock(); }      // we don't have read-write locks
+void Mutex::ReaderUnlock() { Unlock(); }
+
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+
+#define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \
+  if (is_safe_ && fncall(&mutex_) != 0) abort();                           \
+} while (0)
+
+Mutex::Mutex() {
+  SetIsSafe();
+  if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::~Mutex()            { SAFE_PTHREAD(pthread_rwlock_destroy); }
+void Mutex::Lock()         { SAFE_PTHREAD(pthread_rwlock_wrlock); }
+void Mutex::Unlock()       { SAFE_PTHREAD(pthread_rwlock_unlock); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock()      { return is_safe_ ?
+                                    pthread_rwlock_trywrlock(&mutex_) == 0 :
+                                    true; }
+#endif
+void Mutex::ReaderLock()   { SAFE_PTHREAD(pthread_rwlock_rdlock); }
+void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
+#undef SAFE_PTHREAD
+
+#elif defined(HAVE_PTHREAD)
+
+#define SAFE_PTHREAD(fncall)  do {   /* run fncall if is_safe_ is true */  \
+  if (is_safe_ && fncall(&mutex_) != 0) abort();                           \
+} while (0)
+
+Mutex::Mutex()             {
+  SetIsSafe();
+  if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort();
+}
+Mutex::~Mutex()            { SAFE_PTHREAD(pthread_mutex_destroy); }
+void Mutex::Lock()         { SAFE_PTHREAD(pthread_mutex_lock); }
+void Mutex::Unlock()       { SAFE_PTHREAD(pthread_mutex_unlock); }
+#ifdef GMUTEX_TRYLOCK
+bool Mutex::TryLock()      { return is_safe_ ?
+                                 pthread_mutex_trylock(&mutex_) == 0 : true; }
+#endif
+void Mutex::ReaderLock()   { Lock(); }
+void Mutex::ReaderUnlock() { Unlock(); }
+#undef SAFE_PTHREAD
+
+#endif
+
+// --------------------------------------------------------------------------
+// Some helper classes
+
+// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
+class MutexLock {
+ public:
+  explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
+  ~MutexLock() { mu_->Unlock(); }
+ private:
+  Mutex * const mu_;
+  // Disallow "evil" constructors
+  MutexLock(const MutexLock&);
+  void operator=(const MutexLock&);
+};
+
+// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
+class ReaderMutexLock {
+ public:
+  explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
+  ~ReaderMutexLock() { mu_->ReaderUnlock(); }
+ private:
+  Mutex * const mu_;
+  // Disallow "evil" constructors
+  ReaderMutexLock(const ReaderMutexLock&);
+  void operator=(const ReaderMutexLock&);
+};
+
+class WriterMutexLock {
+ public:
+  explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
+  ~WriterMutexLock() { mu_->WriterUnlock(); }
+ private:
+  Mutex * const mu_;
+  // Disallow "evil" constructors
+  WriterMutexLock(const WriterMutexLock&);
+  void operator=(const WriterMutexLock&);
+};
+
+// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
+#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
+#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
+#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)
+
+}  // namespace MUTEX_NAMESPACE
+
+using namespace MUTEX_NAMESPACE;
+
+#undef MUTEX_NAMESPACE
+
+#endif  /* #define GOOGLE_MUTEX_H__ */
diff --git a/third_party/google-glog/src/config.h.cmake.in b/third_party/google-glog/src/config.h.cmake.in
new file mode 100644
index 0000000..ee8cdfe
--- /dev/null
+++ b/third_party/google-glog/src/config.h.cmake.in
@@ -0,0 +1,216 @@
+#ifndef GLOG_CONFIG_H
+#define GLOG_CONFIG_H
+
+/* define if glog doesn't use RTTI */
+#cmakedefine DISABLE_RTTI
+
+/* Namespace for Google classes */
+#cmakedefine GOOGLE_NAMESPACE ${GOOGLE_NAMESPACE}
+
+/* Define if you have the `dladdr' function */
+#cmakedefine HAVE_DLADDR
+
+/* Define if you have the `snprintf' function */
+#cmakedefine HAVE_SNPRINTF
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#cmakedefine HAVE_EXECINFO_H
+
+/* Define if you have the `fcntl' function */
+#cmakedefine HAVE_FCNTL
+
+/* Define to 1 if you have the <glob.h> header file. */
+#cmakedefine HAVE_GLOB_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#cmakedefine HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the <libunwind.h> header file. */
+#cmakedefine HAVE_LIBUNWIND_H
+
+/* define if you have google gflags library */
+#cmakedefine HAVE_LIB_GFLAGS
+
+/* define if you have google gmock library */
+#cmakedefine HAVE_LIB_GMOCK
+
+/* define if you have google gtest library */
+#cmakedefine HAVE_LIB_GTEST
+
+/* define if you have libunwind */
+#cmakedefine HAVE_LIB_UNWIND
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H
+
+/* define to disable multithreading support. */
+#cmakedefine NO_THREADS
+
+/* define if the compiler implements namespaces */
+#cmakedefine HAVE_NAMESPACES
+
+/* Define if you have the 'pread' function */
+#cmakedefine HAVE_PREAD
+
+/* Define if you have POSIX threads libraries and header files. */
+#cmakedefine HAVE_PTHREAD
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#cmakedefine HAVE_PWD_H
+
+/* Define if you have the 'pwrite' function */
+#cmakedefine HAVE_PWRITE
+
+/* define if the compiler implements pthread_rwlock_* */
+#cmakedefine HAVE_RWLOCK
+
+/* Define if you have the 'sigaction' function */
+#cmakedefine HAVE_SIGACTION
+
+/* Define if you have the `sigaltstack' function */
+#cmakedefine HAVE_SIGALTSTACK
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H
+
+/* Define to 1 if you have the <syscall.h> header file. */
+#cmakedefine HAVE_SYSCALL_H
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#cmakedefine HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+#cmakedefine HAVE_SYS_SYSCALL_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#cmakedefine HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
+
+/* Define to 1 if you have the <sys/ucontext.h> header file. */
+#cmakedefine HAVE_SYS_UCONTEXT_H
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#cmakedefine HAVE_SYS_UTSNAME_H
+
+/* Define to 1 if you have the <ucontext.h> header file. */
+#cmakedefine HAVE_UCONTEXT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H}
+
+/* Define to 1 if you have the <unwind.h> header file. */
+#cmakedefine HAVE_UNWIND_H ${HAVE_UNWIND_H}
+
+/* define if the compiler supports using expression for operator */
+#cmakedefine HAVE_USING_OPERATOR
+
+/* define if your compiler has __attribute__ */
+#cmakedefine HAVE___ATTRIBUTE__
+
+/* define if your compiler has __builtin_expect */
+#cmakedefine HAVE___BUILTIN_EXPECT ${HAVE___BUILTIN_EXPECT}
+
+/* define if your compiler has __sync_val_compare_and_swap */
+#cmakedefine HAVE___SYNC_VAL_COMPARE_AND_SWAP
+
+/* define if symbolize support is available */
+#cmakedefine HAVE_SYMBOLIZE
+
+/* define if localtime_r is available in time.h */
+#cmakedefine HAVE_LOCALTIME_R
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#cmakedefine LT_OBJDIR
+
+/* Name of package */
+#cmakedefine PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#cmakedefine PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#cmakedefine PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#cmakedefine PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#cmakedefine PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#cmakedefine PACKAGE_URL
+
+/* Define to the version of this package. */
+#cmakedefine PACKAGE_VERSION
+
+/* How to access the PC from a struct ucontext */
+#cmakedefine PC_FROM_UCONTEXT
+
+/* define if we should print raw pc values on symbolization failure. */
+#cmakedefine PRINT_UNSYMBOLIZED_STACK_TRACES
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#cmakedefine PTHREAD_CREATE_JOINABLE
+
+/* The size of `void *', as computed by sizeof. */
+#cmakedefine SIZEOF_VOID_P ${SIZEOF_VOID_P}
+
+/* Define to 1 if you have the ANSI C header files. */
+#cmakedefine STDC_HEADERS
+
+/* the namespace where STL code like vector<> is defined */
+#cmakedefine STL_NAMESPACE ${STL_NAMESPACE}
+
+/* location of source code */
+#cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR}
+
+/* Define to necessary thread-local storage attribute. */
+#cmakedefine GLOG_THREAD_LOCAL_STORAGE ${GLOG_THREAD_LOCAL_STORAGE}
+
+/* Check whether aligned_storage and alignof present */
+#cmakedefine HAVE_ALIGNED_STORAGE ${HAVE_ALIGNED_STORAGE}
+
+/* Version number of package */
+#cmakedefine VERSION
+
+#ifdef GLOG_BAZEL_BUILD
+
+/* TODO(rodrigoq): remove this workaround once bazel#3979 is resolved:
+ * https://github.com/bazelbuild/bazel/issues/3979 */
+#define _START_GOOGLE_NAMESPACE_ namespace GOOGLE_NAMESPACE {
+
+#define _END_GOOGLE_NAMESPACE_ }
+
+#else
+
+/* Stops putting the code inside the Google namespace */
+#cmakedefine _END_GOOGLE_NAMESPACE_ ${_END_GOOGLE_NAMESPACE_}
+
+/* Puts following code inside the Google namespace */
+#cmakedefine _START_GOOGLE_NAMESPACE_ ${_START_GOOGLE_NAMESPACE_}
+
+#endif
+
+#endif  // GLOG_CONFIG_H
diff --git a/third_party/google-glog/src/config_for_unittests.h b/third_party/google-glog/src/config_for_unittests.h
new file mode 100644
index 0000000..13ea8ea
--- /dev/null
+++ b/third_party/google-glog/src/config_for_unittests.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// All Rights Reserved.
+//
+// Author: Craig Silverstein
+// Copied from google-perftools and modified by Shinichiro Hamaji
+//
+// This file is needed for windows -- unittests are not part of the
+// glog dll, but still want to include config.h just like the
+// dll does, so they can use internal tools and APIs for testing.
+//
+// The problem is that config.h declares GOOGLE_GLOG_DLL_DECL to be
+// for exporting symbols, but the unittest needs to *import* symbols
+// (since it's not the dll).
+//
+// The solution is to have this file, which is just like config.h but
+// sets GOOGLE_GLOG_DLL_DECL to do a dllimport instead of a dllexport.
+//
+// The reason we need this extra GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS
+// variable is in case people want to set GOOGLE_GLOG_DLL_DECL explicitly
+// to something other than __declspec(dllexport).  In that case, they
+// may want to use something other than __declspec(dllimport) for the
+// unittest case.  For that, we allow folks to define both
+// GOOGLE_GLOG_DLL_DECL and GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS explicitly.
+//
+// NOTE: This file is equivalent to config.h on non-windows systems,
+// which never defined GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS and always
+// define GOOGLE_GLOG_DLL_DECL to the empty string.
+
+#include "config.h"
+
+#undef GOOGLE_GLOG_DLL_DECL
+#ifdef GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS
+# define GOOGLE_GLOG_DLL_DECL  GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS
+#else
+// if DLL_DECL_FOR_UNITTESTS isn't defined, use ""
+# define GOOGLE_GLOG_DLL_DECL
+#endif
diff --git a/third_party/google-glog/src/demangle.cc b/third_party/google-glog/src/demangle.cc
new file mode 100644
index 0000000..9369f9a
--- /dev/null
+++ b/third_party/google-glog/src/demangle.cc
@@ -0,0 +1,1356 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// For reference check out:
+// http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
+//
+// Note that we only have partial C++0x support yet.
+
+#include <stdio.h>  // for NULL
+#include "utilities.h"
+#include "demangle.h"
+
+#if defined(OS_WINDOWS)
+#include <dbghelp.h>
+#pragma comment(lib, "dbghelp")
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+#if !defined(OS_WINDOWS)
+typedef struct {
+  const char *abbrev;
+  const char *real_name;
+} AbbrevPair;
+
+// List of operators from Itanium C++ ABI.
+static const AbbrevPair kOperatorList[] = {
+  { "nw", "new" },
+  { "na", "new[]" },
+  { "dl", "delete" },
+  { "da", "delete[]" },
+  { "ps", "+" },
+  { "ng", "-" },
+  { "ad", "&" },
+  { "de", "*" },
+  { "co", "~" },
+  { "pl", "+" },
+  { "mi", "-" },
+  { "ml", "*" },
+  { "dv", "/" },
+  { "rm", "%" },
+  { "an", "&" },
+  { "or", "|" },
+  { "eo", "^" },
+  { "aS", "=" },
+  { "pL", "+=" },
+  { "mI", "-=" },
+  { "mL", "*=" },
+  { "dV", "/=" },
+  { "rM", "%=" },
+  { "aN", "&=" },
+  { "oR", "|=" },
+  { "eO", "^=" },
+  { "ls", "<<" },
+  { "rs", ">>" },
+  { "lS", "<<=" },
+  { "rS", ">>=" },
+  { "eq", "==" },
+  { "ne", "!=" },
+  { "lt", "<" },
+  { "gt", ">" },
+  { "le", "<=" },
+  { "ge", ">=" },
+  { "nt", "!" },
+  { "aa", "&&" },
+  { "oo", "||" },
+  { "pp", "++" },
+  { "mm", "--" },
+  { "cm", "," },
+  { "pm", "->*" },
+  { "pt", "->" },
+  { "cl", "()" },
+  { "ix", "[]" },
+  { "qu", "?" },
+  { "st", "sizeof" },
+  { "sz", "sizeof" },
+  { NULL, NULL },
+};
+
+// List of builtin types from Itanium C++ ABI.
+static const AbbrevPair kBuiltinTypeList[] = {
+  { "v", "void" },
+  { "w", "wchar_t" },
+  { "b", "bool" },
+  { "c", "char" },
+  { "a", "signed char" },
+  { "h", "unsigned char" },
+  { "s", "short" },
+  { "t", "unsigned short" },
+  { "i", "int" },
+  { "j", "unsigned int" },
+  { "l", "long" },
+  { "m", "unsigned long" },
+  { "x", "long long" },
+  { "y", "unsigned long long" },
+  { "n", "__int128" },
+  { "o", "unsigned __int128" },
+  { "f", "float" },
+  { "d", "double" },
+  { "e", "long double" },
+  { "g", "__float128" },
+  { "z", "ellipsis" },
+  { NULL, NULL }
+};
+
+// List of substitutions Itanium C++ ABI.
+static const AbbrevPair kSubstitutionList[] = {
+  { "St", "" },
+  { "Sa", "allocator" },
+  { "Sb", "basic_string" },
+  // std::basic_string<char, std::char_traits<char>,std::allocator<char> >
+  { "Ss", "string"},
+  // std::basic_istream<char, std::char_traits<char> >
+  { "Si", "istream" },
+  // std::basic_ostream<char, std::char_traits<char> >
+  { "So", "ostream" },
+  // std::basic_iostream<char, std::char_traits<char> >
+  { "Sd", "iostream" },
+  { NULL, NULL }
+};
+
+// State needed for demangling.
+typedef struct {
+  const char *mangled_cur;  // Cursor of mangled name.
+  char *out_cur;            // Cursor of output string.
+  const char *out_begin;    // Beginning of output string.
+  const char *out_end;      // End of output string.
+  const char *prev_name;    // For constructors/destructors.
+  int prev_name_length;     // For constructors/destructors.
+  short nest_level;         // For nested names.
+  bool append;              // Append flag.
+  bool overflowed;          // True if output gets overflowed.
+} State;
+
+// We don't use strlen() in libc since it's not guaranteed to be async
+// signal safe.
+static size_t StrLen(const char *str) {
+  size_t len = 0;
+  while (*str != '\0') {
+    ++str;
+    ++len;
+  }
+  return len;
+}
+
+// Returns true if "str" has at least "n" characters remaining.
+static bool AtLeastNumCharsRemaining(const char *str, int n) {
+  for (int i = 0; i < n; ++i) {
+    if (str[i] == '\0') {
+      return false;
+    }
+  }
+  return true;
+}
+
+// Returns true if "str" has "prefix" as a prefix.
+static bool StrPrefix(const char *str, const char *prefix) {
+  size_t i = 0;
+  while (str[i] != '\0' && prefix[i] != '\0' &&
+         str[i] == prefix[i]) {
+    ++i;
+  }
+  return prefix[i] == '\0';  // Consumed everything in "prefix".
+}
+
+static void InitState(State *state, const char *mangled,
+                      char *out, int out_size) {
+  state->mangled_cur = mangled;
+  state->out_cur = out;
+  state->out_begin = out;
+  state->out_end = out + out_size;
+  state->prev_name  = NULL;
+  state->prev_name_length = -1;
+  state->nest_level = -1;
+  state->append = true;
+  state->overflowed = false;
+}
+
+// Returns true and advances "mangled_cur" if we find "one_char_token"
+// at "mangled_cur" position.  It is assumed that "one_char_token" does
+// not contain '\0'.
+static bool ParseOneCharToken(State *state, const char one_char_token) {
+  if (state->mangled_cur[0] == one_char_token) {
+    ++state->mangled_cur;
+    return true;
+  }
+  return false;
+}
+
+// Returns true and advances "mangled_cur" if we find "two_char_token"
+// at "mangled_cur" position.  It is assumed that "two_char_token" does
+// not contain '\0'.
+static bool ParseTwoCharToken(State *state, const char *two_char_token) {
+  if (state->mangled_cur[0] == two_char_token[0] &&
+      state->mangled_cur[1] == two_char_token[1]) {
+    state->mangled_cur += 2;
+    return true;
+  }
+  return false;
+}
+
+// Returns true and advances "mangled_cur" if we find any character in
+// "char_class" at "mangled_cur" position.
+static bool ParseCharClass(State *state, const char *char_class) {
+  const char *p = char_class;
+  for (; *p != '\0'; ++p) {
+    if (state->mangled_cur[0] == *p) {
+      ++state->mangled_cur;
+      return true;
+    }
+  }
+  return false;
+}
+
+// This function is used for handling an optional non-terminal.
+static bool Optional(bool) {
+  return true;
+}
+
+// This function is used for handling <non-terminal>+ syntax.
+typedef bool (*ParseFunc)(State *);
+static bool OneOrMore(ParseFunc parse_func, State *state) {
+  if (parse_func(state)) {
+    while (parse_func(state)) {
+    }
+    return true;
+  }
+  return false;
+}
+
+// This function is used for handling <non-terminal>* syntax. The function
+// always returns true and must be followed by a termination token or a
+// terminating sequence not handled by parse_func (e.g.
+// ParseOneCharToken(state, 'E')).
+static bool ZeroOrMore(ParseFunc parse_func, State *state) {
+  while (parse_func(state)) {
+  }
+  return true;
+}
+
+// Append "str" at "out_cur".  If there is an overflow, "overflowed"
+// is set to true for later use.  The output string is ensured to
+// always terminate with '\0' as long as there is no overflow.
+static void Append(State *state, const char * const str, const int length) {
+  int i;
+  for (i = 0; i < length; ++i) {
+    if (state->out_cur + 1 < state->out_end) {  // +1 for '\0'
+      *state->out_cur = str[i];
+      ++state->out_cur;
+    } else {
+      state->overflowed = true;
+      break;
+    }
+  }
+  if (!state->overflowed) {
+    *state->out_cur = '\0';  // Terminate it with '\0'
+  }
+}
+
+// We don't use equivalents in libc to avoid locale issues.
+static bool IsLower(char c) {
+  return c >= 'a' && c <= 'z';
+}
+
+static bool IsAlpha(char c) {
+  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+static bool IsDigit(char c) {
+  return c >= '0' && c <= '9';
+}
+
+// Returns true if "str" is a function clone suffix.  These suffixes are used
+// by GCC 4.5.x and later versions to indicate functions which have been
+// cloned during optimization.  We treat any sequence (.<alpha>+.<digit>+)+ as
+// a function clone suffix.
+static bool IsFunctionCloneSuffix(const char *str) {
+  size_t i = 0;
+  while (str[i] != '\0') {
+    // Consume a single .<alpha>+.<digit>+ sequence.
+    if (str[i] != '.' || !IsAlpha(str[i + 1])) {
+      return false;
+    }
+    i += 2;
+    while (IsAlpha(str[i])) {
+      ++i;
+    }
+    if (str[i] != '.' || !IsDigit(str[i + 1])) {
+      return false;
+    }
+    i += 2;
+    while (IsDigit(str[i])) {
+      ++i;
+    }
+  }
+  return true;  // Consumed everything in "str".
+}
+
+// Append "str" with some tweaks, iff "append" state is true.
+// Returns true so that it can be placed in "if" conditions.
+static void MaybeAppendWithLength(State *state, const char * const str,
+                                  const int length) {
+  if (state->append && length > 0) {
+    // Append a space if the output buffer ends with '<' and "str"
+    // starts with '<' to avoid <<<.
+    if (str[0] == '<' && state->out_begin < state->out_cur  &&
+        state->out_cur[-1] == '<') {
+      Append(state, " ", 1);
+    }
+    // Remember the last identifier name for ctors/dtors.
+    if (IsAlpha(str[0]) || str[0] == '_') {
+      state->prev_name = state->out_cur;
+      state->prev_name_length = length;
+    }
+    Append(state, str, length);
+  }
+}
+
+// A convenient wrapper arount MaybeAppendWithLength().
+static bool MaybeAppend(State *state, const char * const str) {
+  if (state->append) {
+    int length = StrLen(str);
+    MaybeAppendWithLength(state, str, length);
+  }
+  return true;
+}
+
+// This function is used for handling nested names.
+static bool EnterNestedName(State *state) {
+  state->nest_level = 0;
+  return true;
+}
+
+// This function is used for handling nested names.
+static bool LeaveNestedName(State *state, short prev_value) {
+  state->nest_level = prev_value;
+  return true;
+}
+
+// Disable the append mode not to print function parameters, etc.
+static bool DisableAppend(State *state) {
+  state->append = false;
+  return true;
+}
+
+// Restore the append mode to the previous state.
+static bool RestoreAppend(State *state, bool prev_value) {
+  state->append = prev_value;
+  return true;
+}
+
+// Increase the nest level for nested names.
+static void MaybeIncreaseNestLevel(State *state) {
+  if (state->nest_level > -1) {
+    ++state->nest_level;
+  }
+}
+
+// Appends :: for nested names if necessary.
+static void MaybeAppendSeparator(State *state) {
+  if (state->nest_level >= 1) {
+    MaybeAppend(state, "::");
+  }
+}
+
+// Cancel the last separator if necessary.
+static void MaybeCancelLastSeparator(State *state) {
+  if (state->nest_level >= 1 && state->append &&
+      state->out_begin <= state->out_cur - 2) {
+    state->out_cur -= 2;
+    *state->out_cur = '\0';
+  }
+}
+
+// Returns true if the identifier of the given length pointed to by
+// "mangled_cur" is anonymous namespace.
+static bool IdentifierIsAnonymousNamespace(State *state, int length) {
+  static const char anon_prefix[] = "_GLOBAL__N_";
+  return (length > (int)sizeof(anon_prefix) - 1 &&  // Should be longer.
+          StrPrefix(state->mangled_cur, anon_prefix));
+}
+
+// Forward declarations of our parsing functions.
+static bool ParseMangledName(State *state);
+static bool ParseEncoding(State *state);
+static bool ParseName(State *state);
+static bool ParseUnscopedName(State *state);
+static bool ParseUnscopedTemplateName(State *state);
+static bool ParseNestedName(State *state);
+static bool ParsePrefix(State *state);
+static bool ParseUnqualifiedName(State *state);
+static bool ParseSourceName(State *state);
+static bool ParseLocalSourceName(State *state);
+static bool ParseNumber(State *state, int *number_out);
+static bool ParseFloatNumber(State *state);
+static bool ParseSeqId(State *state);
+static bool ParseIdentifier(State *state, int length);
+static bool ParseAbiTags(State *state);
+static bool ParseAbiTag(State *state);
+static bool ParseOperatorName(State *state);
+static bool ParseSpecialName(State *state);
+static bool ParseCallOffset(State *state);
+static bool ParseNVOffset(State *state);
+static bool ParseVOffset(State *state);
+static bool ParseCtorDtorName(State *state);
+static bool ParseType(State *state);
+static bool ParseCVQualifiers(State *state);
+static bool ParseBuiltinType(State *state);
+static bool ParseFunctionType(State *state);
+static bool ParseBareFunctionType(State *state);
+static bool ParseClassEnumType(State *state);
+static bool ParseArrayType(State *state);
+static bool ParsePointerToMemberType(State *state);
+static bool ParseTemplateParam(State *state);
+static bool ParseTemplateTemplateParam(State *state);
+static bool ParseTemplateArgs(State *state);
+static bool ParseTemplateArg(State *state);
+static bool ParseExpression(State *state);
+static bool ParseExprPrimary(State *state);
+static bool ParseLocalName(State *state);
+static bool ParseDiscriminator(State *state);
+static bool ParseSubstitution(State *state);
+
+// Implementation note: the following code is a straightforward
+// translation of the Itanium C++ ABI defined in BNF with a couple of
+// exceptions.
+//
+// - Support GNU extensions not defined in the Itanium C++ ABI
+// - <prefix> and <template-prefix> are combined to avoid infinite loop
+// - Reorder patterns to shorten the code
+// - Reorder patterns to give greedier functions precedence
+//   We'll mark "Less greedy than" for these cases in the code
+//
+// Each parsing function changes the state and returns true on
+// success.  Otherwise, don't change the state and returns false.  To
+// ensure that the state isn't changed in the latter case, we save the
+// original state before we call more than one parsing functions
+// consecutively with &&, and restore the state if unsuccessful.  See
+// ParseEncoding() as an example of this convention.  We follow the
+// convention throughout the code.
+//
+// Originally we tried to do demangling without following the full ABI
+// syntax but it turned out we needed to follow the full syntax to
+// parse complicated cases like nested template arguments.  Note that
+// implementing a full-fledged demangler isn't trivial (libiberty's
+// cp-demangle.c has +4300 lines).
+//
+// Note that (foo) in <(foo) ...> is a modifier to be ignored.
+//
+// Reference:
+// - Itanium C++ ABI
+//   <http://www.codesourcery.com/cxx-abi/abi.html#mangling>
+
+// <mangled-name> ::= _Z <encoding>
+static bool ParseMangledName(State *state) {
+  return ParseTwoCharToken(state, "_Z") && ParseEncoding(state);
+}
+
+// <encoding> ::= <(function) name> <bare-function-type>
+//            ::= <(data) name>
+//            ::= <special-name>
+static bool ParseEncoding(State *state) {
+  State copy = *state;
+  if (ParseName(state) && ParseBareFunctionType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseName(state) || ParseSpecialName(state)) {
+    return true;
+  }
+  return false;
+}
+
+// <name> ::= <nested-name>
+//        ::= <unscoped-template-name> <template-args>
+//        ::= <unscoped-name>
+//        ::= <local-name>
+static bool ParseName(State *state) {
+  if (ParseNestedName(state) || ParseLocalName(state)) {
+    return true;
+  }
+
+  State copy = *state;
+  if (ParseUnscopedTemplateName(state) &&
+      ParseTemplateArgs(state)) {
+    return true;
+  }
+  *state = copy;
+
+  // Less greedy than <unscoped-template-name> <template-args>.
+  if (ParseUnscopedName(state)) {
+    return true;
+  }
+  return false;
+}
+
+// <unscoped-name> ::= <unqualified-name>
+//                 ::= St <unqualified-name>
+static bool ParseUnscopedName(State *state) {
+  if (ParseUnqualifiedName(state)) {
+    return true;
+  }
+
+  State copy = *state;
+  if (ParseTwoCharToken(state, "St") &&
+      MaybeAppend(state, "std::") &&
+      ParseUnqualifiedName(state)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <unscoped-template-name> ::= <unscoped-name>
+//                          ::= <substitution>
+static bool ParseUnscopedTemplateName(State *state) {
+  return ParseUnscopedName(state) || ParseSubstitution(state);
+}
+
+// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
+//               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
+static bool ParseNestedName(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'N') &&
+      EnterNestedName(state) &&
+      Optional(ParseCVQualifiers(state)) &&
+      ParsePrefix(state) &&
+      LeaveNestedName(state, copy.nest_level) &&
+      ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// This part is tricky.  If we literally translate them to code, we'll
+// end up infinite loop.  Hence we merge them to avoid the case.
+//
+// <prefix> ::= <prefix> <unqualified-name>
+//          ::= <template-prefix> <template-args>
+//          ::= <template-param>
+//          ::= <substitution>
+//          ::= # empty
+// <template-prefix> ::= <prefix> <(template) unqualified-name>
+//                   ::= <template-param>
+//                   ::= <substitution>
+static bool ParsePrefix(State *state) {
+  bool has_something = false;
+  while (true) {
+    MaybeAppendSeparator(state);
+    if (ParseTemplateParam(state) ||
+        ParseSubstitution(state) ||
+        ParseUnscopedName(state)) {
+      has_something = true;
+      MaybeIncreaseNestLevel(state);
+      continue;
+    }
+    MaybeCancelLastSeparator(state);
+    if (has_something && ParseTemplateArgs(state)) {
+      return ParsePrefix(state);
+    } else {
+      break;
+    }
+  }
+  return true;
+}
+
+// <unqualified-name> ::= <operator-name>
+//                    ::= <ctor-dtor-name>
+//                    ::= <source-name> [<abi-tags>]
+//                    ::= <local-source-name> [<abi-tags>]
+static bool ParseUnqualifiedName(State *state) {
+  return (ParseOperatorName(state) ||
+          ParseCtorDtorName(state) ||
+          (ParseSourceName(state) && Optional(ParseAbiTags(state))) ||
+          (ParseLocalSourceName(state) && Optional(ParseAbiTags(state))));
+}
+
+// <source-name> ::= <positive length number> <identifier>
+static bool ParseSourceName(State *state) {
+  State copy = *state;
+  int length = -1;
+  if (ParseNumber(state, &length) && ParseIdentifier(state, length)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <local-source-name> ::= L <source-name> [<discriminator>]
+//
+// References:
+//   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
+//   http://gcc.gnu.org/viewcvs?view=rev&revision=124467
+static bool ParseLocalSourceName(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'L') && ParseSourceName(state) &&
+      Optional(ParseDiscriminator(state))) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <number> ::= [n] <non-negative decimal integer>
+// If "number_out" is non-null, then *number_out is set to the value of the
+// parsed number on success.
+static bool ParseNumber(State *state, int *number_out) {
+  int sign = 1;
+  if (ParseOneCharToken(state, 'n')) {
+    sign = -1;
+  }
+  const char *p = state->mangled_cur;
+  int number = 0;
+  for (;*p != '\0'; ++p) {
+    if (IsDigit(*p)) {
+      number = number * 10 + (*p - '0');
+    } else {
+      break;
+    }
+  }
+  if (p != state->mangled_cur) {  // Conversion succeeded.
+    state->mangled_cur = p;
+    if (number_out != NULL) {
+      *number_out = number * sign;
+    }
+    return true;
+  }
+  return false;
+}
+
+// Floating-point literals are encoded using a fixed-length lowercase
+// hexadecimal string.
+static bool ParseFloatNumber(State *state) {
+  const char *p = state->mangled_cur;
+  for (;*p != '\0'; ++p) {
+    if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) {
+      break;
+    }
+  }
+  if (p != state->mangled_cur) {  // Conversion succeeded.
+    state->mangled_cur = p;
+    return true;
+  }
+  return false;
+}
+
+// The <seq-id> is a sequence number in base 36,
+// using digits and upper case letters
+static bool ParseSeqId(State *state) {
+  const char *p = state->mangled_cur;
+  for (;*p != '\0'; ++p) {
+    if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) {
+      break;
+    }
+  }
+  if (p != state->mangled_cur) {  // Conversion succeeded.
+    state->mangled_cur = p;
+    return true;
+  }
+  return false;
+}
+
+// <identifier> ::= <unqualified source code identifier> (of given length)
+static bool ParseIdentifier(State *state, int length) {
+  if (length == -1 ||
+      !AtLeastNumCharsRemaining(state->mangled_cur, length)) {
+    return false;
+  }
+  if (IdentifierIsAnonymousNamespace(state, length)) {
+    MaybeAppend(state, "(anonymous namespace)");
+  } else {
+    MaybeAppendWithLength(state, state->mangled_cur, length);
+  }
+  state->mangled_cur += length;
+  return true;
+}
+
+// <abi-tags> ::= <abi-tag> [<abi-tags>]
+static bool ParseAbiTags(State *state) {
+  State copy = *state;
+  DisableAppend(state);
+  if (OneOrMore(ParseAbiTag, state)) {
+    RestoreAppend(state, copy.append);
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <abi-tag> ::= B <source-name>
+static bool ParseAbiTag(State *state) {
+  return ParseOneCharToken(state, 'B') && ParseSourceName(state);
+}
+
+// <operator-name> ::= nw, and other two letters cases
+//                 ::= cv <type>  # (cast)
+//                 ::= v  <digit> <source-name> # vendor extended operator
+static bool ParseOperatorName(State *state) {
+  if (!AtLeastNumCharsRemaining(state->mangled_cur, 2)) {
+    return false;
+  }
+  // First check with "cv" (cast) case.
+  State copy = *state;
+  if (ParseTwoCharToken(state, "cv") &&
+      MaybeAppend(state, "operator ") &&
+      EnterNestedName(state) &&
+      ParseType(state) &&
+      LeaveNestedName(state, copy.nest_level)) {
+    return true;
+  }
+  *state = copy;
+
+  // Then vendor extended operators.
+  if (ParseOneCharToken(state, 'v') && ParseCharClass(state, "0123456789") &&
+      ParseSourceName(state)) {
+    return true;
+  }
+  *state = copy;
+
+  // Other operator names should start with a lower alphabet followed
+  // by a lower/upper alphabet.
+  if (!(IsLower(state->mangled_cur[0]) &&
+        IsAlpha(state->mangled_cur[1]))) {
+    return false;
+  }
+  // We may want to perform a binary search if we really need speed.
+  const AbbrevPair *p;
+  for (p = kOperatorList; p->abbrev != NULL; ++p) {
+    if (state->mangled_cur[0] == p->abbrev[0] &&
+        state->mangled_cur[1] == p->abbrev[1]) {
+      MaybeAppend(state, "operator");
+      if (IsLower(*p->real_name)) {  // new, delete, etc.
+        MaybeAppend(state, " ");
+      }
+      MaybeAppend(state, p->real_name);
+      state->mangled_cur += 2;
+      return true;
+    }
+  }
+  return false;
+}
+
+// <special-name> ::= TV <type>
+//                ::= TT <type>
+//                ::= TI <type>
+//                ::= TS <type>
+//                ::= Tc <call-offset> <call-offset> <(base) encoding>
+//                ::= GV <(object) name>
+//                ::= T <call-offset> <(base) encoding>
+// G++ extensions:
+//                ::= TC <type> <(offset) number> _ <(base) type>
+//                ::= TF <type>
+//                ::= TJ <type>
+//                ::= GR <name>
+//                ::= GA <encoding>
+//                ::= Th <call-offset> <(base) encoding>
+//                ::= Tv <call-offset> <(base) encoding>
+//
+// Note: we don't care much about them since they don't appear in
+// stack traces.  The are special data.
+static bool ParseSpecialName(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'T') &&
+      ParseCharClass(state, "VTIS") &&
+      ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "Tc") && ParseCallOffset(state) &&
+      ParseCallOffset(state) && ParseEncoding(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "GV") &&
+      ParseName(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'T') && ParseCallOffset(state) &&
+      ParseEncoding(state)) {
+    return true;
+  }
+  *state = copy;
+
+  // G++ extensions
+  if (ParseTwoCharToken(state, "TC") && ParseType(state) &&
+      ParseNumber(state, NULL) && ParseOneCharToken(state, '_') &&
+      DisableAppend(state) &&
+      ParseType(state)) {
+    RestoreAppend(state, copy.append);
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "FJ") &&
+      ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "GR") && ParseName(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "GA") && ParseEncoding(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") &&
+      ParseCallOffset(state) && ParseEncoding(state)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <call-offset> ::= h <nv-offset> _
+//               ::= v <v-offset> _
+static bool ParseCallOffset(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'h') &&
+      ParseNVOffset(state) && ParseOneCharToken(state, '_')) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'v') &&
+      ParseVOffset(state) && ParseOneCharToken(state, '_')) {
+    return true;
+  }
+  *state = copy;
+
+  return false;
+}
+
+// <nv-offset> ::= <(offset) number>
+static bool ParseNVOffset(State *state) {
+  return ParseNumber(state, NULL);
+}
+
+// <v-offset>  ::= <(offset) number> _ <(virtual offset) number>
+static bool ParseVOffset(State *state) {
+  State copy = *state;
+  if (ParseNumber(state, NULL) && ParseOneCharToken(state, '_') &&
+      ParseNumber(state, NULL)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <ctor-dtor-name> ::= C1 | C2 | C3
+//                  ::= D0 | D1 | D2
+static bool ParseCtorDtorName(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'C') &&
+      ParseCharClass(state, "123")) {
+    const char * const prev_name = state->prev_name;
+    const int prev_name_length = state->prev_name_length;
+    MaybeAppendWithLength(state, prev_name, prev_name_length);
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'D') &&
+      ParseCharClass(state, "012")) {
+    const char * const prev_name = state->prev_name;
+    const int prev_name_length = state->prev_name_length;
+    MaybeAppend(state, "~");
+    MaybeAppendWithLength(state, prev_name, prev_name_length);
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <type> ::= <CV-qualifiers> <type>
+//        ::= P <type>   # pointer-to
+//        ::= R <type>   # reference-to
+//        ::= O <type>   # rvalue reference-to (C++0x)
+//        ::= C <type>   # complex pair (C 2000)
+//        ::= G <type>   # imaginary (C 2000)
+//        ::= U <source-name> <type>  # vendor extended type qualifier
+//        ::= <builtin-type>
+//        ::= <function-type>
+//        ::= <class-enum-type>
+//        ::= <array-type>
+//        ::= <pointer-to-member-type>
+//        ::= <template-template-param> <template-args>
+//        ::= <template-param>
+//        ::= <substitution>
+//        ::= Dp <type>          # pack expansion of (C++0x)
+//        ::= Dt <expression> E  # decltype of an id-expression or class
+//                               # member access (C++0x)
+//        ::= DT <expression> E  # decltype of an expression (C++0x)
+//
+static bool ParseType(State *state) {
+  // We should check CV-qualifers, and PRGC things first.
+  State copy = *state;
+  if (ParseCVQualifiers(state) && ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseCharClass(state, "OPRCG") && ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "Dp") && ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") &&
+      ParseExpression(state) && ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'U') && ParseSourceName(state) &&
+      ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseBuiltinType(state) ||
+      ParseFunctionType(state) ||
+      ParseClassEnumType(state) ||
+      ParseArrayType(state) ||
+      ParsePointerToMemberType(state) ||
+      ParseSubstitution(state)) {
+    return true;
+  }
+
+  if (ParseTemplateTemplateParam(state) &&
+      ParseTemplateArgs(state)) {
+    return true;
+  }
+  *state = copy;
+
+  // Less greedy than <template-template-param> <template-args>.
+  if (ParseTemplateParam(state)) {
+    return true;
+  }
+
+  return false;
+}
+
+// <CV-qualifiers> ::= [r] [V] [K]
+// We don't allow empty <CV-qualifiers> to avoid infinite loop in
+// ParseType().
+static bool ParseCVQualifiers(State *state) {
+  int num_cv_qualifiers = 0;
+  num_cv_qualifiers += ParseOneCharToken(state, 'r');
+  num_cv_qualifiers += ParseOneCharToken(state, 'V');
+  num_cv_qualifiers += ParseOneCharToken(state, 'K');
+  return num_cv_qualifiers > 0;
+}
+
+// <builtin-type> ::= v, etc.
+//                ::= u <source-name>
+static bool ParseBuiltinType(State *state) {
+  const AbbrevPair *p;
+  for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) {
+    if (state->mangled_cur[0] == p->abbrev[0]) {
+      MaybeAppend(state, p->real_name);
+      ++state->mangled_cur;
+      return true;
+    }
+  }
+
+  State copy = *state;
+  if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <function-type> ::= F [Y] <bare-function-type> E
+static bool ParseFunctionType(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'F') &&
+      Optional(ParseOneCharToken(state, 'Y')) &&
+      ParseBareFunctionType(state) && ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <bare-function-type> ::= <(signature) type>+
+static bool ParseBareFunctionType(State *state) {
+  State copy = *state;
+  DisableAppend(state);
+  if (OneOrMore(ParseType, state)) {
+    RestoreAppend(state, copy.append);
+    MaybeAppend(state, "()");
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <class-enum-type> ::= <name>
+static bool ParseClassEnumType(State *state) {
+  return ParseName(state);
+}
+
+// <array-type> ::= A <(positive dimension) number> _ <(element) type>
+//              ::= A [<(dimension) expression>] _ <(element) type>
+static bool ParseArrayType(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'A') && ParseNumber(state, NULL) &&
+      ParseOneCharToken(state, '_') && ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) &&
+      ParseOneCharToken(state, '_') && ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <pointer-to-member-type> ::= M <(class) type> <(member) type>
+static bool ParsePointerToMemberType(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'M') && ParseType(state) &&
+      ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <template-param> ::= T_
+//                  ::= T <parameter-2 non-negative number> _
+static bool ParseTemplateParam(State *state) {
+  if (ParseTwoCharToken(state, "T_")) {
+    MaybeAppend(state, "?");  // We don't support template substitutions.
+    return true;
+  }
+
+  State copy = *state;
+  if (ParseOneCharToken(state, 'T') && ParseNumber(state, NULL) &&
+      ParseOneCharToken(state, '_')) {
+    MaybeAppend(state, "?");  // We don't support template substitutions.
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+
+// <template-template-param> ::= <template-param>
+//                           ::= <substitution>
+static bool ParseTemplateTemplateParam(State *state) {
+  return (ParseTemplateParam(state) ||
+          ParseSubstitution(state));
+}
+
+// <template-args> ::= I <template-arg>+ E
+static bool ParseTemplateArgs(State *state) {
+  State copy = *state;
+  DisableAppend(state);
+  if (ParseOneCharToken(state, 'I') &&
+      OneOrMore(ParseTemplateArg, state) &&
+      ParseOneCharToken(state, 'E')) {
+    RestoreAppend(state, copy.append);
+    MaybeAppend(state, "<>");
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <template-arg>  ::= <type>
+//                 ::= <expr-primary>
+//                 ::= I <template-arg>* E        # argument pack
+//                 ::= J <template-arg>* E        # argument pack
+//                 ::= X <expression> E
+static bool ParseTemplateArg(State *state) {
+  State copy = *state;
+  if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
+      ZeroOrMore(ParseTemplateArg, state) &&
+      ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseType(state) ||
+      ParseExprPrimary(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
+      ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <expression> ::= <template-param>
+//              ::= <expr-primary>
+//              ::= <unary operator-name> <expression>
+//              ::= <binary operator-name> <expression> <expression>
+//              ::= <trinary operator-name> <expression> <expression>
+//                  <expression>
+//              ::= st <type>
+//              ::= sr <type> <unqualified-name> <template-args>
+//              ::= sr <type> <unqualified-name>
+static bool ParseExpression(State *state) {
+  if (ParseTemplateParam(state) || ParseExprPrimary(state)) {
+    return true;
+  }
+
+  State copy = *state;
+  if (ParseOperatorName(state) &&
+      ParseExpression(state) &&
+      ParseExpression(state) &&
+      ParseExpression(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOperatorName(state) &&
+      ParseExpression(state) &&
+      ParseExpression(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOperatorName(state) &&
+      ParseExpression(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "st") && ParseType(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
+      ParseUnqualifiedName(state) &&
+      ParseTemplateArgs(state)) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
+      ParseUnqualifiedName(state)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <expr-primary> ::= L <type> <(value) number> E
+//                ::= L <type> <(value) float> E
+//                ::= L <mangled-name> E
+//                // A bug in g++'s C++ ABI version 2 (-fabi-version=2).
+//                ::= LZ <encoding> E
+static bool ParseExprPrimary(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
+      ParseNumber(state, NULL) &&
+      ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
+      ParseFloatNumber(state) &&
+      ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'L') && ParseMangledName(state) &&
+      ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseTwoCharToken(state, "LZ") && ParseEncoding(state) &&
+      ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  *state = copy;
+
+  return false;
+}
+
+// <local-name> := Z <(function) encoding> E <(entity) name>
+//                 [<discriminator>]
+//              := Z <(function) encoding> E s [<discriminator>]
+static bool ParseLocalName(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
+      ParseOneCharToken(state, 'E') && MaybeAppend(state, "::") &&
+      ParseName(state) && Optional(ParseDiscriminator(state))) {
+    return true;
+  }
+  *state = copy;
+
+  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
+      ParseTwoCharToken(state, "Es") && Optional(ParseDiscriminator(state))) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <discriminator> := _ <(non-negative) number>
+static bool ParseDiscriminator(State *state) {
+  State copy = *state;
+  if (ParseOneCharToken(state, '_') && ParseNumber(state, NULL)) {
+    return true;
+  }
+  *state = copy;
+  return false;
+}
+
+// <substitution> ::= S_
+//                ::= S <seq-id> _
+//                ::= St, etc.
+static bool ParseSubstitution(State *state) {
+  if (ParseTwoCharToken(state, "S_")) {
+    MaybeAppend(state, "?");  // We don't support substitutions.
+    return true;
+  }
+
+  State copy = *state;
+  if (ParseOneCharToken(state, 'S') && ParseSeqId(state) &&
+      ParseOneCharToken(state, '_')) {
+    MaybeAppend(state, "?");  // We don't support substitutions.
+    return true;
+  }
+  *state = copy;
+
+  // Expand abbreviations like "St" => "std".
+  if (ParseOneCharToken(state, 'S')) {
+    const AbbrevPair *p;
+    for (p = kSubstitutionList; p->abbrev != NULL; ++p) {
+      if (state->mangled_cur[0] == p->abbrev[1]) {
+        MaybeAppend(state, "std");
+        if (p->real_name[0] != '\0') {
+          MaybeAppend(state, "::");
+          MaybeAppend(state, p->real_name);
+        }
+        ++state->mangled_cur;
+        return true;
+      }
+    }
+  }
+  *state = copy;
+  return false;
+}
+
+// Parse <mangled-name>, optionally followed by either a function-clone suffix
+// or version suffix.  Returns true only if all of "mangled_cur" was consumed.
+static bool ParseTopLevelMangledName(State *state) {
+  if (ParseMangledName(state)) {
+    if (state->mangled_cur[0] != '\0') {
+      // Drop trailing function clone suffix, if any.
+      if (IsFunctionCloneSuffix(state->mangled_cur)) {
+        return true;
+      }
+      // Append trailing version suffix if any.
+      // ex. _Z3foo@@GLIBCXX_3.4
+      if (state->mangled_cur[0] == '@') {
+        MaybeAppend(state, state->mangled_cur);
+        return true;
+      }
+      return false;  // Unconsumed suffix.
+    }
+    return true;
+  }
+  return false;
+}
+#endif
+
+// The demangler entry point.
+bool Demangle(const char *mangled, char *out, int out_size) {
+#if defined(OS_WINDOWS)
+  // When built with incremental linking, the Windows debugger
+  // library provides a more complicated `Symbol->Name` with the
+  // Incremental Linking Table offset, which looks like
+  // `@ILT+1105(?func@Foo@@SAXH@Z)`. However, the demangler expects
+  // only the mangled symbol, `?func@Foo@@SAXH@Z`. Fortunately, the
+  // mangled symbol is guaranteed not to have parentheses,
+  // so we search for `(` and extract up to `)`.
+  //
+  // Since we may be in a signal handler here, we cannot use `std::string`.
+  char buffer[1024];  // Big enough for a sane symbol.
+  const char *lparen = strchr(mangled, '(');
+  if (lparen) {
+    // Extract the string `(?...)`
+    const char *rparen = strchr(lparen, ')');
+    size_t length = rparen - lparen - 1;
+    strncpy(buffer, lparen + 1, length);
+    buffer[length] = '\0';
+    mangled = buffer;
+  } // Else the symbol wasn't inside a set of parentheses
+  // We use the ANSI version to ensure the string type is always `char *`.
+  return UnDecorateSymbolName(mangled, out, out_size, UNDNAME_COMPLETE);
+#else
+  State state;
+  InitState(&state, mangled, out, out_size);
+  return ParseTopLevelMangledName(&state) && !state.overflowed;
+#endif
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/demangle.h b/third_party/google-glog/src/demangle.h
new file mode 100644
index 0000000..991b6ff
--- /dev/null
+++ b/third_party/google-glog/src/demangle.h
@@ -0,0 +1,85 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// An async-signal-safe and thread-safe demangler for Itanium C++ ABI
+// (aka G++ V3 ABI).
+
+// The demangler is implemented to be used in async signal handlers to
+// symbolize stack traces.  We cannot use libstdc++'s
+// abi::__cxa_demangle() in such signal handlers since it's not async
+// signal safe (it uses malloc() internally).
+//
+// Note that this demangler doesn't support full demangling.  More
+// specifically, it doesn't print types of function parameters and
+// types of template arguments.  It just skips them.  However, it's
+// still very useful to extract basic information such as class,
+// function, constructor, destructor, and operator names.
+//
+// See the implementation note in demangle.cc if you are interested.
+//
+// Example:
+//
+// | Mangled Name  | The Demangler | abi::__cxa_demangle()
+// |---------------|---------------|-----------------------
+// | _Z1fv         | f()           | f()
+// | _Z1fi         | f()           | f(int)
+// | _Z3foo3bar    | foo()         | foo(bar)
+// | _Z1fIiEvi     | f<>()         | void f<int>(int)
+// | _ZN1N1fE      | N::f          | N::f
+// | _ZN3Foo3BarEv | Foo::Bar()    | Foo::Bar()
+// | _Zrm1XS_"     | operator%()   | operator%(X, X)
+// | _ZN3FooC1Ev   | Foo::Foo()    | Foo::Foo()
+// | _Z1fSs        | f()           | f(std::basic_string<char,
+// |               |               |   std::char_traits<char>,
+// |               |               |   std::allocator<char> >)
+//
+// See the unit test for more examples.
+//
+// Note: we might want to write demanglers for ABIs other than Itanium
+// C++ ABI in the future.
+//
+
+#ifndef BASE_DEMANGLE_H_
+#define BASE_DEMANGLE_H_
+
+#include "config.h"
+#include "glog/logging.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// Demangle "mangled".  On success, return true and write the
+// demangled symbol name to "out".  Otherwise, return false.
+// "out" is modified even if demangling is unsuccessful.
+bool GOOGLE_GLOG_DLL_DECL Demangle(const char *mangled, char *out, int out_size);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif  // BASE_DEMANGLE_H_
diff --git a/third_party/google-glog/src/demangle_unittest.cc b/third_party/google-glog/src/demangle_unittest.cc
new file mode 100644
index 0000000..be48341
--- /dev/null
+++ b/third_party/google-glog/src/demangle_unittest.cc
@@ -0,0 +1,168 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// Unit tests for functions in demangle.c.
+
+#include "utilities.h"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include "glog/logging.h"
+#include "demangle.h"
+#include "googletest.h"
+#include "config.h"
+
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+using namespace GFLAGS_NAMESPACE;
+#endif
+
+GLOG_DEFINE_bool(demangle_filter, false,
+                 "Run demangle_unittest in filter mode");
+
+using namespace std;
+using namespace GOOGLE_NAMESPACE;
+
+// A wrapper function for Demangle() to make the unit test simple.
+static const char *DemangleIt(const char * const mangled) {
+  static char demangled[4096];
+  if (Demangle(mangled, demangled, sizeof(demangled))) {
+    return demangled;
+  } else {
+    return mangled;
+  }
+}
+
+#if defined(OS_WINDOWS)
+
+TEST(Demangle, Windows) {
+  EXPECT_STREQ(
+    "public: static void __cdecl Foo::func(int)",
+    DemangleIt("?func@Foo@@SAXH@Z"));
+  EXPECT_STREQ(
+    "public: static void __cdecl Foo::func(int)",
+    DemangleIt("@ILT+1105(?func@Foo@@SAXH@Z)"));
+  EXPECT_STREQ(
+    "int __cdecl foobarArray(int * const)",
+    DemangleIt("?foobarArray@@YAHQAH@Z"));
+}
+
+#else
+
+// Test corner cases of bounary conditions.
+TEST(Demangle, CornerCases) {
+  const size_t size = 10;
+  char tmp[size] = { 0 };
+  const char *demangled = "foobar()";
+  const char *mangled = "_Z6foobarv";
+  EXPECT_TRUE(Demangle(mangled, tmp, sizeof(tmp)));
+  // sizeof("foobar()") == size - 1
+  EXPECT_STREQ(demangled, tmp);
+  EXPECT_TRUE(Demangle(mangled, tmp, size - 1));
+  EXPECT_STREQ(demangled, tmp);
+  EXPECT_FALSE(Demangle(mangled, tmp, size - 2));  // Not enough.
+  EXPECT_FALSE(Demangle(mangled, tmp, 1));
+  EXPECT_FALSE(Demangle(mangled, tmp, 0));
+  EXPECT_FALSE(Demangle(mangled, NULL, 0));  // Should not cause SEGV.
+}
+
+// Test handling of functions suffixed with .clone.N, which is used by GCC
+// 4.5.x, and .constprop.N and .isra.N, which are used by GCC 4.6.x.  These
+// suffixes are used to indicate functions which have been cloned during
+// optimization.  We ignore these suffixes.
+TEST(Demangle, Clones) {
+  char tmp[20];
+  EXPECT_TRUE(Demangle("_ZL3Foov", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  EXPECT_TRUE(Demangle("_ZL3Foov.clone.3", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  EXPECT_TRUE(Demangle("_ZL3Foov.constprop.80", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  EXPECT_TRUE(Demangle("_ZL3Foov.isra.18", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp)));
+  EXPECT_STREQ("Foo()", tmp);
+  // Invalid (truncated), should not demangle.
+  EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp)));
+  // Invalid (.clone. not followed by number), should not demangle.
+  EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp)));
+  // Invalid (.clone. followed by non-number), should not demangle.
+  EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp)));
+  // Invalid (.constprop. not followed by number), should not demangle.
+  EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
+}
+
+TEST(Demangle, FromFile) {
+  string test_file = FLAGS_test_srcdir + "/src/demangle_unittest.txt";
+  ifstream f(test_file.c_str());  // The file should exist.
+  EXPECT_FALSE(f.fail());
+
+  string line;
+  while (getline(f, line)) {
+    // Lines start with '#' are considered as comments.
+    if (line.empty() || line[0] == '#') {
+      continue;
+    }
+    // Each line should contain a mangled name and a demangled name
+    // separated by '\t'.  Example: "_Z3foo\tfoo"
+    string::size_type tab_pos = line.find('\t');
+    EXPECT_NE(string::npos, tab_pos);
+    string mangled = line.substr(0, tab_pos);
+    string demangled = line.substr(tab_pos + 1);
+    EXPECT_EQ(demangled, DemangleIt(mangled.c_str()));
+  }
+}
+
+#endif
+
+int main(int argc, char **argv) {
+#ifdef HAVE_LIB_GFLAGS
+  ParseCommandLineFlags(&argc, &argv, true);
+#endif
+  InitGoogleTest(&argc, argv);
+
+  FLAGS_logtostderr = true;
+  InitGoogleLogging(argv[0]);
+  if (FLAGS_demangle_filter) {
+    // Read from cin and write to cout.
+    string line;
+    while (getline(cin, line, '\n')) {
+      cout << DemangleIt(line.c_str()) << endl;
+    }
+    return 0;
+  } else if (argc > 1) {
+    cout << DemangleIt(argv[1]) << endl;
+    return 0;
+  } else {
+    return RUN_ALL_TESTS();
+  }
+}
diff --git a/third_party/google-glog/src/demangle_unittest.sh b/third_party/google-glog/src/demangle_unittest.sh
new file mode 100755
index 0000000..91deee2
--- /dev/null
+++ b/third_party/google-glog/src/demangle_unittest.sh
@@ -0,0 +1,95 @@
+#! /bin/sh
+#
+# Copyright (c) 2006, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: Satoru Takabayashi
+#
+# Unit tests for demangle.c with a real binary.
+
+set -e
+
+die () {
+    echo $1
+    exit 1
+}
+
+BINDIR=".libs"
+LIBGLOG="$BINDIR/libglog.so"
+
+DEMANGLER="$BINDIR/demangle_unittest"
+
+if test -e "$DEMANGLER"; then
+  # We need shared object.
+  export LD_LIBRARY_PATH=$BINDIR
+  export DYLD_LIBRARY_PATH=$BINDIR
+else
+  # For windows
+  DEMANGLER="./demangle_unittest.exe"
+  if ! test -e "$DEMANGLER"; then
+    echo "We coundn't find demangle_unittest binary."
+    exit 1
+  fi
+fi
+
+# Extract C++ mangled symbols from libbase.so.
+NM_OUTPUT="demangle.nm"
+nm "$LIBGLOG" | perl -nle 'print $1 if /\s(_Z\S+$)/' > "$NM_OUTPUT"
+
+# Check if mangled symbols exist. If there are none, we quit.
+# The binary is more likely compiled with GCC 2.95 or something old.
+if ! grep --quiet '^_Z' "$NM_OUTPUT"; then
+    echo "PASS"
+    exit 0
+fi
+
+# Demangle the symbols using our demangler.
+DM_OUTPUT="demangle.dm"
+GLOG_demangle_filter=1 "$DEMANGLER" --demangle_filter < "$NM_OUTPUT" > "$DM_OUTPUT"
+
+# Calculate the numbers of lines.
+NM_LINES=`wc -l "$NM_OUTPUT" | awk '{ print $1 }'`
+DM_LINES=`wc -l "$DM_OUTPUT" | awk '{ print $1 }'`
+
+# Compare the numbers of lines.  They must be the same.
+if test "$NM_LINES" != "$DM_LINES"; then
+    die "$NM_OUTPUT and $DM_OUTPUT don't have the same numbers of lines"
+fi
+
+# Check if mangled symbols exist.  They must not exist.
+if grep --quiet '^_Z' "$DM_OUTPUT"; then
+    MANGLED=`grep '^_Z' "$DM_OUTPUT" | wc -l | awk '{ print \$1 }'`
+    echo "Mangled symbols ($MANGLED out of $NM_LINES) found in $DM_OUTPUT:"
+    grep '^_Z' "$DM_OUTPUT"
+    die "Mangled symbols ($MANGLED out of $NM_LINES) found in $DM_OUTPUT"
+fi
+
+# All C++ symbols are demangled successfully.
+echo "PASS"
+exit 0
diff --git a/third_party/google-glog/src/demangle_unittest.txt b/third_party/google-glog/src/demangle_unittest.txt
new file mode 100644
index 0000000..07e28bc
--- /dev/null
+++ b/third_party/google-glog/src/demangle_unittest.txt
@@ -0,0 +1,145 @@
+# Test caces for demangle_unittest.  Each line consists of a
+# tab-separated pair of mangled and demangled symbol names.
+
+# Constructors and destructors.
+_ZN3FooC1Ev	Foo::Foo()
+_ZN3FooD1Ev	Foo::~Foo()
+_ZNSoD0Ev	std::ostream::~ostream()
+
+# G++ extensions.
+_ZTCN10LogMessage9LogStreamE0_So	LogMessage::LogStream
+_ZTv0_n12_N10LogMessage9LogStreamD0Ev	LogMessage::LogStream::~LogStream()
+_ZThn4_N7icu_3_410UnicodeSetD0Ev	icu_3_4::UnicodeSet::~UnicodeSet()
+
+# A bug in g++'s C++ ABI version 2 (-fabi-version=2).
+_ZN7NSSInfoI5groupjjXadL_Z10getgrgid_rEELZ19nss_getgrgid_r_nameEEC1Ei	NSSInfo<>::NSSInfo()
+
+# C linkage symbol names.  Should keep them untouched.
+main	main
+Demangle	Demangle
+_ZERO	_ZERO
+
+# Cast operator.
+_Zcviv	operator int()
+_ZN3foocviEv	foo::operator int()
+
+# Versioned symbols.
+_Z3Foo@GLIBCXX_3.4	Foo@GLIBCXX_3.4
+_Z3Foo@@GLIBCXX_3.4	Foo@@GLIBCXX_3.4
+
+# Abbreviations.
+_ZNSaE	std::allocator
+_ZNSbE	std::basic_string
+_ZNSdE	std::iostream
+_ZNSiE	std::istream
+_ZNSoE	std::ostream
+_ZNSsE	std::string
+
+# Substitutions.  We just replace them with ?.
+_ZN3fooS_E	foo::?
+_ZN3foo3barS0_E	foo::bar::?
+_ZNcvT_IiEEv	operator ?<>()
+
+# "<< <" case.
+_ZlsI3fooE	operator<< <>
+
+# ABI tags.
+_Z1AB3barB3foo	A
+_ZN3fooL3barB5cxx11E	foo::bar
+
+# Random things we found interesting.
+_ZN3FooISt6vectorISsSaISsEEEclEv	Foo<>::operator()()
+_ZTI9Callback1IiE	Callback1<>
+_ZN7icu_3_47UMemorynwEj	icu_3_4::UMemory::operator new()
+_ZNSt6vectorIbE9push_backE	std::vector<>::push_back
+_ZNSt6vectorIbSaIbEE9push_backEb	std::vector<>::push_back()
+_ZlsRSoRK15PRIVATE_Counter	operator<<()
+_ZSt6fill_nIPPN9__gnu_cxx15_Hashtable_nodeISt4pairIKPKcjEEEjS8_ET_SA_T0_RKT1_	std::fill_n<>()
+_ZZ3FoovE3Bar	Foo()::Bar
+_ZGVZ7UpTimervE8up_timer	UpTimer()::up_timer
+
+# Test cases from gcc-4.1.0/libstdc++-v3/testsuite/demangle.
+# Collected by:
+# % grep verify_demangle **/*.cc | perl -nle 'print $1 if /"(_Z.*?)"/' |
+#   sort | uniq
+#
+# Note that the following symbols are invalid.
+# That's why they are not demangled.
+# - _ZNZN1N1fEiE1X1gE
+# - _ZNZN1N1fEiE1X1gEv
+# - _Z1xINiEE
+_Z1fA37_iPS_	f()
+_Z1fAszL_ZZNK1N1A1fEvE3foo_0E_i	f()
+_Z1fI1APS0_PKS0_EvT_T0_T1_PA4_S3_M1CS8_	f<>()
+_Z1fI1XENT_1tES2_	f<>()
+_Z1fI1XEvPVN1AIT_E1TE	f<>()
+_Z1fILi1ELc120EEv1AIXplT_cviLd4028ae147ae147aeEEE	f<>()
+_Z1fILi1ELc120EEv1AIXplT_cviLf3f800000EEE	f<>()
+_Z1fILi5E1AEvN1CIXqugtT_Li0ELi1ELi2EEE1qE	f<>()
+_Z1fILi5E1AEvN1CIXstN1T1tEEXszsrS2_1tEE1qE	f<>()
+_Z1fILi5EEvN1AIXcvimlT_Li22EEE1qE	f<>()
+_Z1fIiEvi	f<>()
+_Z1fKPFiiE	f()
+_Z1fM1AFivEPS0_	f()
+_Z1fM1AKFivE	f()
+_Z1fM1AKFvvE	f()
+_Z1fPFPA1_ivE	f()
+_Z1fPFYPFiiEiE	f()
+_Z1fPFvvEM1SFvvE	f()
+_Z1fPKM1AFivE	f()
+_Z1fi	f()
+_Z1fv	f()
+_Z1jM1AFivEPS1_	j()
+_Z1rM1GFivEMS_KFivES_M1HFivES1_4whatIKS_E5what2IS8_ES3_	r()
+_Z1sPA37_iPS0_	s()
+_Z1xINiEE	_Z1xINiEE
+_Z3absILi11EEvv	abs<>()
+_Z3foo3bar	foo()
+_Z3foo5Hello5WorldS0_S_	foo()
+_Z3fooA30_A_i	foo()
+_Z3fooIA6_KiEvA9_KT_rVPrS4_	foo<>()
+_Z3fooILi2EEvRAplT_Li1E_i	foo<>()
+_Z3fooIiFvdEiEvv	foo<>()
+_Z3fooPM2ABi	foo()
+_Z3fooc	foo()
+_Z3fooiPiPS_PS0_PS1_PS2_PS3_PS4_PS5_PS6_PS7_PS8_PS9_PSA_PSB_PSC_	foo()
+_Z3kooPA28_A30_i	koo()
+_Z4makeI7FactoryiET_IT0_Ev	make<>()
+_Z5firstI3DuoEvS0_	first<>()
+_Z5firstI3DuoEvT_	first<>()
+_Z9hairyfuncM1YKFPVPFrPA2_PM1XKFKPA3_ilEPcEiE	hairyfunc()
+_ZGVN5libcw24_GLOBAL__N_cbll.cc0ZhUKa23compiler_bug_workaroundISt6vectorINS_13omanip_id_tctINS_5debug32memblk_types_manipulator_data_ctEEESaIS6_EEE3idsE	libcw::(anonymous namespace)::compiler_bug_workaround<>::ids
+_ZN12libcw_app_ct10add_optionIS_EEvMT_FvPKcES3_cS3_S3_	libcw_app_ct::add_option<>()
+_ZN1AIfEcvT_IiEEv	A<>::operator ?<>()
+_ZN1N1TIiiE2mfES0_IddE	N::T<>::mf()
+_ZN1N1fE	N::f
+_ZN1f1fE	f::f
+_ZN3FooIA4_iE3barE	Foo<>::bar
+_ZN5Arena5levelE	Arena::level
+_ZN5StackIiiE5levelE	Stack<>::level
+_ZN5libcw5debug13cwprint_usingINS_9_private_12GlobalObjectEEENS0_17cwprint_using_tctIT_EERKS5_MS5_KFvRSt7ostreamE	libcw::debug::cwprint_using<>()
+_ZN6System5Sound4beepEv	System::Sound::beep()
+_ZNKSt14priority_queueIP27timer_event_request_base_ctSt5dequeIS1_SaIS1_EE13timer_greaterE3topEv	std::priority_queue<>::top()
+_ZNKSt15_Deque_iteratorIP15memory_block_stRKS1_PS2_EeqERKS5_	std::_Deque_iterator<>::operator==()
+_ZNKSt17__normal_iteratorIPK6optionSt6vectorIS0_SaIS0_EEEmiERKS6_	std::__normal_iterator<>::operator-()
+_ZNSbIcSt11char_traitsIcEN5libcw5debug27no_alloc_checking_allocatorEE12_S_constructIPcEES6_T_S7_RKS3_	std::basic_string<>::_S_construct<>()
+_ZNSt13_Alloc_traitsISbIcSt18string_char_traitsIcEN5libcw5debug9_private_17allocator_adaptorIcSt24__default_alloc_templateILb0ELi327664EELb1EEEENS5_IS9_S7_Lb1EEEE15_S_instancelessE	std::_Alloc_traits<>::_S_instanceless
+_ZNSt3_In4wardE	std::_In::ward
+_ZNZN1N1fEiE1X1gE	_ZNZN1N1fEiE1X1gE
+_ZNZN1N1fEiE1X1gEv	_ZNZN1N1fEiE1X1gEv
+_ZSt1BISt1DIP1ARKS2_PS3_ES0_IS2_RS2_PS2_ES2_ET0_T_SB_SA_PT1_	std::B<>()
+_ZSt5state	std::state
+_ZTI7a_class	a_class
+_ZZN1N1fEiE1p	N::f()::p
+_ZZN1N1fEiEs	N::f()
+_ZlsRK1XS1_	operator<<()
+_ZlsRKU3fooU4bart1XS0_	operator<<()
+_ZlsRKU3fooU4bart1XS2_	operator<<()
+_ZlsRSoRKSs	operator<<()
+_ZngILi42EEvN1AIXplT_Li2EEE1TE	operator-<>()
+_ZplR1XS0_	operator+()
+_Zrm1XS_	operator%()
+
+# Template argument packs can start with I or J.
+_Z3addIIiEEvDpT_	add<>()
+_Z3addIJiEEvDpT_	add<>()
diff --git a/third_party/google-glog/src/glog/log_severity.h b/third_party/google-glog/src/glog/log_severity.h
new file mode 100644
index 0000000..99945a4
--- /dev/null
+++ b/third_party/google-glog/src/glog/log_severity.h
@@ -0,0 +1,92 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef BASE_LOG_SEVERITY_H__
+#define BASE_LOG_SEVERITY_H__
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+#   define GOOGLE_GLOG_DLL_DECL  __declspec(dllimport)
+# else
+#   define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// Variables of type LogSeverity are widely taken to lie in the range
+// [0, NUM_SEVERITIES-1].  Be careful to preserve this assumption if
+// you ever need to change their values or add a new severity.
+typedef int LogSeverity;
+
+const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
+  NUM_SEVERITIES = 4;
+#ifndef GLOG_NO_ABBREVIATED_SEVERITIES
+# ifdef ERROR
+#  error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail.
+# endif
+const int INFO = GLOG_INFO, WARNING = GLOG_WARNING,
+  ERROR = GLOG_ERROR, FATAL = GLOG_FATAL;
+#endif
+
+// DFATAL is FATAL in debug mode, ERROR in normal mode
+#ifdef NDEBUG
+#define DFATAL_LEVEL ERROR
+#else
+#define DFATAL_LEVEL FATAL
+#endif
+
+extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES];
+
+// NDEBUG usage helpers related to (RAW_)DCHECK:
+//
+// DEBUG_MODE is for small !NDEBUG uses like
+//   if (DEBUG_MODE) foo.CheckThatFoo();
+// instead of substantially more verbose
+//   #ifndef NDEBUG
+//     foo.CheckThatFoo();
+//   #endif
+//
+// IF_DEBUG_MODE is for small !NDEBUG uses like
+//   IF_DEBUG_MODE( string error; )
+//   DCHECK(Foo(&error)) << error;
+// instead of substantially more verbose
+//   #ifndef NDEBUG
+//     string error;
+//     DCHECK(Foo(&error)) << error;
+//   #endif
+//
+#ifdef NDEBUG
+enum { DEBUG_MODE = 0 };
+#define IF_DEBUG_MODE(x)
+#else
+enum { DEBUG_MODE = 1 };
+#define IF_DEBUG_MODE(x) x
+#endif
+
+#endif  // BASE_LOG_SEVERITY_H__
diff --git a/third_party/google-glog/src/glog/logging.h.in b/third_party/google-glog/src/glog/logging.h.in
new file mode 100644
index 0000000..448253f
--- /dev/null
+++ b/third_party/google-glog/src/glog/logging.h.in
@@ -0,0 +1,1658 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney
+//
+// This file contains #include information about logging-related stuff.
+// Pretty much everybody needs to #include this file so that they can
+// log various happenings.
+//
+#ifndef _LOGGING_H_
+#define _LOGGING_H_
+
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <iosfwd>
+#include <ostream>
+#include <sstream>
+#include <string>
+#if @ac_cv_have_unistd_h@
+# include <unistd.h>
+#endif
+#include <vector>
+
+#if defined(_MSC_VER)
+#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \
+                                     __pragma(warning(disable:n))
+#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop))
+#else
+#define GLOG_MSVC_PUSH_DISABLE_WARNING(n)
+#define GLOG_MSVC_POP_WARNING()
+#endif
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+#   define GOOGLE_GLOG_DLL_DECL  __declspec(dllimport)
+# else
+#   define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// We care a lot about number of bits things take up.  Unfortunately,
+// systems define their bit-specific ints in a lot of different ways.
+// We use our own way, and have a typedef to get there.
+// Note: these commands below may look like "#if 1" or "#if 0", but
+// that's because they were constructed that way at ./configure time.
+// Look at logging.h.in to see how they're calculated (based on your config).
+#if @ac_cv_have_stdint_h@
+#include <stdint.h>             // the normal place uint16_t is defined
+#endif
+#if @ac_cv_have_systypes_h@
+#include <sys/types.h>          // the normal place u_int16_t is defined
+#endif
+#if @ac_cv_have_inttypes_h@
+#include <inttypes.h>           // a third place for uint16_t or u_int16_t
+#endif
+
+#if @ac_cv_have_libgflags@
+#include <gflags/gflags.h>
+#endif
+
+@ac_google_start_namespace@
+
+#if @ac_cv_have_uint16_t@      // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif @ac_cv_have_u_int16_t@   // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif @ac_cv_have___uint16@    // the windows (vc7) format
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+
+@ac_google_end_namespace@
+
+// The global value of GOOGLE_STRIP_LOG. All the messages logged to
+// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed.
+// If it can be determined at compile time that the message will not be
+// printed, the statement will be compiled out.
+//
+// Example: to strip out all INFO and WARNING messages, use the value
+// of 2 below. To make an exception for WARNING messages from a single
+// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including
+// base/logging.h
+#ifndef GOOGLE_STRIP_LOG
+#define GOOGLE_STRIP_LOG 0
+#endif
+
+// GCC can be told that a certain branch is not likely to be taken (for
+// instance, a CHECK failure), and use that information in static analysis.
+// Giving it this information can help it optimize for the common case in
+// the absence of better information (ie. -fprofile-arcs).
+//
+#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
+#if @ac_cv_have___builtin_expect@
+#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
+#else
+#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
+#endif
+#endif
+
+#ifndef GOOGLE_PREDICT_FALSE
+#if @ac_cv_have___builtin_expect@
+#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
+#else
+#define GOOGLE_PREDICT_FALSE(x) x
+#endif
+#endif
+
+#ifndef GOOGLE_PREDICT_TRUE
+#if @ac_cv_have___builtin_expect@
+#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
+#else
+#define GOOGLE_PREDICT_TRUE(x) x
+#endif
+#endif
+
+
+// Make a bunch of macros for logging.  The way to log things is to stream
+// things to LOG(<a particular severity level>).  E.g.,
+//
+//   LOG(INFO) << "Found " << num_cookies << " cookies";
+//
+// You can capture log messages in a string, rather than reporting them
+// immediately:
+//
+//   vector<string> errors;
+//   LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num;
+//
+// This pushes back the new error onto 'errors'; if given a NULL pointer,
+// it reports the error via LOG(ERROR).
+//
+// You can also do conditional logging:
+//
+//   LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+// You can also do occasional logging (log every n'th occurrence of an
+// event):
+//
+//   LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
+//
+// The above will cause log messages to be output on the 1st, 11th, 21st, ...
+// times it is executed.  Note that the special google::COUNTER value is used
+// to identify which repetition is happening.
+//
+// You can also do occasional conditional logging (log every n'th
+// occurrence of an event, when condition is satisfied):
+//
+//   LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER
+//                                           << "th big cookie";
+//
+// You can log messages the first N times your code executes a line. E.g.
+//
+//   LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie";
+//
+// Outputs log messages for the first 20 times it is executed.
+//
+// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available.
+// These log to syslog as well as to the normal logs.  If you use these at
+// all, you need to be aware that syslog can drastically reduce performance,
+// especially if it is configured for remote logging!  Don't use these
+// unless you fully understand this and have a concrete need to use them.
+// Even then, try to minimize your use of them.
+//
+// There are also "debug mode" logging macros like the ones above:
+//
+//   DLOG(INFO) << "Found cookies";
+//
+//   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+//   DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
+//
+// All "debug mode" logging is compiled away to nothing for non-debug mode
+// compiles.
+//
+// We also have
+//
+//   LOG_ASSERT(assertion);
+//   DLOG_ASSERT(assertion);
+//
+// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion;
+//
+// There are "verbose level" logging macros.  They look like
+//
+//   VLOG(1) << "I'm printed when you run the program with --v=1 or more";
+//   VLOG(2) << "I'm printed when you run the program with --v=2 or more";
+//
+// These always log at the INFO log level (when they log at all).
+// The verbose logging can also be turned on module-by-module.  For instance,
+//    --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
+// will cause:
+//   a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc}
+//   b. VLOG(1) and lower messages to be printed from file.{h,cc}
+//   c. VLOG(3) and lower messages to be printed from files prefixed with "gfs"
+//   d. VLOG(0) and lower messages to be printed from elsewhere
+//
+// The wildcarding functionality shown by (c) supports both '*' (match
+// 0 or more characters) and '?' (match any single character) wildcards.
+//
+// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as
+//
+//   if (VLOG_IS_ON(2)) {
+//     // do some logging preparation and logging
+//     // that can't be accomplished with just VLOG(2) << ...;
+//   }
+//
+// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level"
+// condition macros for sample cases, when some extra computation and
+// preparation for logs is not needed.
+//   VLOG_IF(1, (size > 1024))
+//      << "I'm printed when size is more than 1024 and when you run the "
+//         "program with --v=1 or more";
+//   VLOG_EVERY_N(1, 10)
+//      << "I'm printed every 10th occurrence, and when you run the program "
+//         "with --v=1 or more. Present occurence is " << google::COUNTER;
+//   VLOG_IF_EVERY_N(1, (size > 1024), 10)
+//      << "I'm printed on every 10th occurence of case when size is more "
+//         " than 1024, when you run the program with --v=1 or more. ";
+//         "Present occurence is " << google::COUNTER;
+//
+// The supported severity levels for macros that allow you to specify one
+// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL.
+// Note that messages of a given severity are logged not only in the
+// logfile for that severity, but also in all logfiles of lower severity.
+// E.g., a message of severity FATAL will be logged to the logfiles of
+// severity FATAL, ERROR, WARNING, and INFO.
+//
+// There is also the special severity of DFATAL, which logs FATAL in
+// debug mode, ERROR in normal mode.
+//
+// Very important: logging a message at the FATAL severity level causes
+// the program to terminate (after the message is logged).
+//
+// Unless otherwise specified, logs will be written to the filename
+// "<program name>.<hostname>.<user name>.log.<severity level>.", followed
+// by the date, time, and pid (you can't prevent the date, time, and pid
+// from being in the filename).
+//
+// The logging code takes two flags:
+//     --v=#           set the verbose level
+//     --logtostderr   log all the messages to stderr instead of to logfiles
+
+// LOG LINE PREFIX FORMAT
+//
+// Log lines have this form:
+//
+//     Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
+//
+// where the fields are defined as follows:
+//
+//   L                A single character, representing the log level
+//                    (eg 'I' for INFO)
+//   mm               The month (zero padded; ie May is '05')
+//   dd               The day (zero padded)
+//   hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
+//   threadid         The space-padded thread ID as returned by GetTID()
+//                    (this matches the PID on Linux)
+//   file             The file name
+//   line             The line number
+//   msg              The user-supplied message
+//
+// Example:
+//
+//   I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog
+//   I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395
+//
+// NOTE: although the microseconds are useful for comparing events on
+// a single machine, clocks on different machines may not be well
+// synchronized.  Hence, use caution when comparing the low bits of
+// timestamps from different machines.
+
+#ifndef DECLARE_VARIABLE
+#define MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#define DECLARE_VARIABLE(type, shorttype, name, tn)                     \
+  namespace fL##shorttype {                                             \
+    extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name;                      \
+  }                                                                     \
+  using fL##shorttype::FLAGS_##name
+
+// bool specialization
+#define DECLARE_bool(name) \
+  DECLARE_VARIABLE(bool, B, name, bool)
+
+// int32 specialization
+#define DECLARE_int32(name) \
+  DECLARE_VARIABLE(@ac_google_namespace@::int32, I, name, int32)
+
+// Special case for string, because we have to specify the namespace
+// std::string, which doesn't play nicely with our FLAG__namespace hackery.
+#define DECLARE_string(name)                                            \
+  namespace fLS {                                                       \
+    extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name;              \
+  }                                                                     \
+  using fLS::FLAGS_##name
+#endif
+
+// Set whether log messages go to stderr instead of logfiles
+DECLARE_bool(logtostderr);
+
+// Set whether log messages go to stderr in addition to logfiles.
+DECLARE_bool(alsologtostderr);
+
+// Set color messages logged to stderr (if supported by terminal).
+DECLARE_bool(colorlogtostderr);
+
+// Log messages at a level >= this flag are automatically sent to
+// stderr in addition to log files.
+DECLARE_int32(stderrthreshold);
+
+// Set whether the log prefix should be prepended to each line of output.
+DECLARE_bool(log_prefix);
+
+// Log messages at a level <= this flag are buffered.
+// Log messages at a higher level are flushed immediately.
+DECLARE_int32(logbuflevel);
+
+// Sets the maximum number of seconds which logs may be buffered for.
+DECLARE_int32(logbufsecs);
+
+// Log suppression level: messages logged at a lower level than this
+// are suppressed.
+DECLARE_int32(minloglevel);
+
+// If specified, logfiles are written into this directory instead of the
+// default logging directory.
+DECLARE_string(log_dir);
+
+// Set the log file mode.
+DECLARE_int32(logfile_mode);
+
+// Sets the path of the directory into which to put additional links
+// to the log files.
+DECLARE_string(log_link);
+
+DECLARE_int32(v);  // in vlog_is_on.cc
+
+// Sets the maximum log file size (in MB).
+DECLARE_int32(max_log_size);
+
+// Sets whether to avoid logging to the disk if the disk is full.
+DECLARE_bool(stop_logging_if_full_disk);
+
+#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#undef DECLARE_VARIABLE
+#undef DECLARE_bool
+#undef DECLARE_int32
+#undef DECLARE_string
+#endif
+
+// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for
+// security reasons. See LOG(severtiy) below.
+
+// A few definitions of macros that don't generate much code.  Since
+// LOG(INFO) and its ilk are used all over our code, it's
+// better to have compact code for these operations.
+
+#if GOOGLE_STRIP_LOG == 0
+#define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::LogMessage( \
+      __FILE__, __LINE__)
+#define LOG_TO_STRING_INFO(message) @ac_google_namespace@::LogMessage( \
+      __FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, message)
+#else
+#define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::NullStream()
+#define LOG_TO_STRING_INFO(message) @ac_google_namespace@::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 1
+#define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::LogMessage( \
+      __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING)
+#define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::LogMessage( \
+      __FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, message)
+#else
+#define COMPACT_GOOGLE_LOG_WARNING @ac_google_namespace@::NullStream()
+#define LOG_TO_STRING_WARNING(message) @ac_google_namespace@::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 2
+#define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::LogMessage( \
+      __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR)
+#define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::LogMessage( \
+      __FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, message)
+#else
+#define COMPACT_GOOGLE_LOG_ERROR @ac_google_namespace@::NullStream()
+#define LOG_TO_STRING_ERROR(message) @ac_google_namespace@::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 3
+#define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::LogMessageFatal( \
+      __FILE__, __LINE__)
+#define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::LogMessage( \
+      __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, message)
+#else
+#define COMPACT_GOOGLE_LOG_FATAL @ac_google_namespace@::NullStreamFatal()
+#define LOG_TO_STRING_FATAL(message) @ac_google_namespace@::NullStreamFatal()
+#endif
+
+#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
+#define DCHECK_IS_ON() 0
+#else
+#define DCHECK_IS_ON() 1
+#endif
+
+// For DFATAL, we want to use LogMessage (as opposed to
+// LogMessageFatal), to be consistent with the original behavior.
+#if !DCHECK_IS_ON()
+#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR
+#elif GOOGLE_STRIP_LOG <= 3
+#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::LogMessage( \
+      __FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL)
+#else
+#define COMPACT_GOOGLE_LOG_DFATAL @ac_google_namespace@::NullStreamFatal()
+#endif
+
+#define GOOGLE_LOG_INFO(counter) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, &@ac_google_namespace@::LogMessage::SendToLog)
+#define SYSLOG_INFO(counter) \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_INFO, counter, \
+  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_WARNING(counter)  \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \
+  &@ac_google_namespace@::LogMessage::SendToLog)
+#define SYSLOG_WARNING(counter)  \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_WARNING, counter, \
+  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_ERROR(counter)  \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \
+  &@ac_google_namespace@::LogMessage::SendToLog)
+#define SYSLOG_ERROR(counter)  \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, counter, \
+  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_FATAL(counter) \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \
+  &@ac_google_namespace@::LogMessage::SendToLog)
+#define SYSLOG_FATAL(counter) \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_FATAL, counter, \
+  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_DFATAL(counter) \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \
+  &@ac_google_namespace@::LogMessage::SendToLog)
+#define SYSLOG_DFATAL(counter) \
+  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::DFATAL_LEVEL, counter, \
+  &@ac_google_namespace@::LogMessage::SendToSyslogAndLog)
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
+// A very useful logging macro to log windows errors:
+#define LOG_SYSRESULT(result) \
+  if (FAILED(HRESULT_FROM_WIN32(result))) { \
+    LPSTR message = NULL; \
+    LPSTR msg = reinterpret_cast<LPSTR>(&message); \
+    DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
+                         FORMAT_MESSAGE_FROM_SYSTEM, \
+                         0, result, 0, msg, 100, NULL); \
+    if (message_length > 0) { \
+      @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_ERROR, 0, \
+          &@ac_google_namespace@::LogMessage::SendToLog).stream() \
+          << reinterpret_cast<const char*>(message); \
+      LocalFree(message); \
+    } \
+  }
+#endif
+
+// We use the preprocessor's merging operator, "##", so that, e.g.,
+// LOG(INFO) becomes the token GOOGLE_LOG_INFO.  There's some funny
+// subtle difference between ostream member streaming functions (e.g.,
+// ostream::operator<<(int) and ostream non-member streaming functions
+// (e.g., ::operator<<(ostream&, string&): it turns out that it's
+// impossible to stream something like a string directly to an unnamed
+// ostream. We employ a neat hack by calling the stream() member
+// function of LogMessage which seems to avoid the problem.
+#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
+#define SYSLOG(severity) SYSLOG_ ## severity(0).stream()
+
+@ac_google_start_namespace@
+
+// They need the definitions of integer types.
+#include "glog/log_severity.h"
+#include "glog/vlog_is_on.h"
+
+// Initialize google's logging library. You will see the program name
+// specified by argv0 in log outputs.
+GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0);
+
+// Shutdown google's logging library.
+GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging();
+
+// Install a function which will be called after LOG(FATAL).
+GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)());
+
+class LogSink;  // defined below
+
+// If a non-NULL sink pointer is given, we push this message to that sink.
+// For LOG_TO_SINK we then do normal LOG(severity) logging as well.
+// This is useful for capturing messages and passing/storing them
+// somewhere more specific than the global log of the process.
+// Argument types:
+//   LogSink* sink;
+//   LogSeverity severity;
+// The cast is to disambiguate NULL arguments.
+#define LOG_TO_SINK(sink, severity) \
+  @ac_google_namespace@::LogMessage(                                    \
+      __FILE__, __LINE__,                                               \
+      @ac_google_namespace@::GLOG_ ## severity,                         \
+      static_cast<@ac_google_namespace@::LogSink*>(sink), true).stream()
+#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity)                  \
+  @ac_google_namespace@::LogMessage(                                    \
+      __FILE__, __LINE__,                                               \
+      @ac_google_namespace@::GLOG_ ## severity,                         \
+      static_cast<@ac_google_namespace@::LogSink*>(sink), false).stream()
+
+// If a non-NULL string pointer is given, we write this message to that string.
+// We then do normal LOG(severity) logging as well.
+// This is useful for capturing messages and storing them somewhere more
+// specific than the global log of the process.
+// Argument types:
+//   string* message;
+//   LogSeverity severity;
+// The cast is to disambiguate NULL arguments.
+// NOTE: LOG(severity) expands to LogMessage().stream() for the specified
+// severity.
+#define LOG_TO_STRING(severity, message) \
+  LOG_TO_STRING_##severity(static_cast<string*>(message)).stream()
+
+// If a non-NULL pointer is given, we push the message onto the end
+// of a vector of strings; otherwise, we report it with LOG(severity).
+// This is handy for capturing messages and perhaps passing them back
+// to the caller, rather than reporting them immediately.
+// Argument types:
+//   LogSeverity severity;
+//   vector<string> *outvec;
+// The cast is to disambiguate NULL arguments.
+#define LOG_STRING(severity, outvec) \
+  LOG_TO_STRING_##severity(static_cast<std::vector<std::string>*>(outvec)).stream()
+
+#define LOG_IF(severity, condition) \
+  !(condition) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity)
+#define SYSLOG_IF(severity, condition) \
+  !(condition) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & SYSLOG(severity)
+
+#define LOG_ASSERT(condition)  \
+  LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
+#define SYSLOG_ASSERT(condition) \
+  SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
+
+// CHECK dies with a fatal error if condition is not true.  It is *not*
+// controlled by DCHECK_IS_ON(), so the check will be executed regardless of
+// compilation mode.  Therefore, it is safe to do things like:
+//    CHECK(fp->Write(x) == 4)
+#define CHECK(condition)  \
+      LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
+             << "Check failed: " #condition " "
+
+// A container for a string pointer which can be evaluated to a bool -
+// true iff the pointer is NULL.
+struct CheckOpString {
+  CheckOpString(std::string* str) : str_(str) { }
+  // No destructor: if str_ is non-NULL, we're about to LOG(FATAL),
+  // so there's no point in cleaning up str_.
+  operator bool() const {
+    return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL);
+  }
+  std::string* str_;
+};
+
+// Function is overloaded for integral types to allow static const
+// integrals declared in classes and not defined to be used as arguments to
+// CHECK* macros. It's not encouraged though.
+template <class T>
+inline const T&       GetReferenceableValue(const T&           t) { return t; }
+inline char           GetReferenceableValue(char               t) { return t; }
+inline unsigned char  GetReferenceableValue(unsigned char      t) { return t; }
+inline signed char    GetReferenceableValue(signed char        t) { return t; }
+inline short          GetReferenceableValue(short              t) { return t; }
+inline unsigned short GetReferenceableValue(unsigned short     t) { return t; }
+inline int            GetReferenceableValue(int                t) { return t; }
+inline unsigned int   GetReferenceableValue(unsigned int       t) { return t; }
+inline long           GetReferenceableValue(long               t) { return t; }
+inline unsigned long  GetReferenceableValue(unsigned long      t) { return t; }
+inline long long      GetReferenceableValue(long long          t) { return t; }
+inline unsigned long long GetReferenceableValue(unsigned long long t) {
+  return t;
+}
+
+// This is a dummy class to define the following operator.
+struct DummyClassToDefineOperator {};
+
+@ac_google_end_namespace@
+
+// Define global operator<< to declare using ::operator<<.
+// This declaration will allow use to use CHECK macros for user
+// defined classes which have operator<< (e.g., stl_logging.h).
+inline std::ostream& operator<<(
+    std::ostream& out, const google::DummyClassToDefineOperator&) {
+  return out;
+}
+
+@ac_google_start_namespace@
+
+// This formats a value for a failing CHECK_XX statement.  Ordinarily,
+// it uses the definition for operator<<, with a few special cases below.
+template <typename T>
+inline void MakeCheckOpValueString(std::ostream* os, const T& v) {
+  (*os) << v;
+}
+
+// Overrides for char types provide readable values for unprintable
+// characters.
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const char& v);
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const signed char& v);
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);
+
+// Build the error message string. Specify no inlining for code size.
+template <typename T1, typename T2>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext)
+    @ac_cv___attribute___noinline@;
+
+namespace base {
+namespace internal {
+
+// If "s" is less than base_logging::INFO, returns base_logging::INFO.
+// If "s" is greater than base_logging::FATAL, returns
+// base_logging::ERROR.  Otherwise, returns "s".
+LogSeverity NormalizeSeverity(LogSeverity s);
+
+}  // namespace internal
+
+// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
+// statement.  See MakeCheckOpString for sample usage.  Other
+// approaches were considered: use of a template method (e.g.,
+// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1,
+// base::Print<T2>, &v2), however this approach has complications
+// related to volatile arguments and function-pointer arguments).
+class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder {
+ public:
+  // Inserts "exprtext" and " (" to the stream.
+  explicit CheckOpMessageBuilder(const char *exprtext);
+  // Deletes "stream_".
+  ~CheckOpMessageBuilder();
+  // For inserting the first variable.
+  std::ostream* ForVar1() { return stream_; }
+  // For inserting the second variable (adds an intermediate " vs. ").
+  std::ostream* ForVar2();
+  // Get the result (inserts the closing ")").
+  std::string* NewString();
+
+ private:
+  std::ostringstream *stream_;
+};
+
+}  // namespace base
+
+template <typename T1, typename T2>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) {
+  base::CheckOpMessageBuilder comb(exprtext);
+  MakeCheckOpValueString(comb.ForVar1(), v1);
+  MakeCheckOpValueString(comb.ForVar2(), v2);
+  return comb.NewString();
+}
+
+// Helper functions for CHECK_OP macro.
+// The (int, int) specialization works around the issue that the compiler
+// will not instantiate the template version of the function on values of
+// unnamed enum type - see comment below.
+#define DEFINE_CHECK_OP_IMPL(name, op) \
+  template <typename T1, typename T2> \
+  inline std::string* name##Impl(const T1& v1, const T2& v2,    \
+                            const char* exprtext) { \
+    if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \
+    else return MakeCheckOpString(v1, v2, exprtext); \
+  } \
+  inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \
+    return name##Impl<int, int>(v1, v2, exprtext); \
+  }
+
+// We use the full name Check_EQ, Check_NE, etc. in case the file including
+// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
+// This happens if, for example, those are used as token names in a
+// yacc grammar.
+DEFINE_CHECK_OP_IMPL(Check_EQ, ==)  // Compilation error with CHECK_EQ(NULL, x)?
+DEFINE_CHECK_OP_IMPL(Check_NE, !=)  // Use CHECK(x == NULL) instead.
+DEFINE_CHECK_OP_IMPL(Check_LE, <=)
+DEFINE_CHECK_OP_IMPL(Check_LT, < )
+DEFINE_CHECK_OP_IMPL(Check_GE, >=)
+DEFINE_CHECK_OP_IMPL(Check_GT, > )
+#undef DEFINE_CHECK_OP_IMPL
+
+// Helper macro for binary operators.
+// Don't use this macro directly in your code, use CHECK_EQ et al below.
+
+#if defined(STATIC_ANALYSIS)
+// Only for static analysis tool to know that it is equivalent to assert
+#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2))
+#elif DCHECK_IS_ON()
+// In debug mode, avoid constructing CheckOpStrings if possible,
+// to reduce the overhead of CHECK statments by 2x.
+// Real DCHECK-heavy tests have seen 1.5x speedups.
+
+// The meaning of "string" might be different between now and
+// when this macro gets invoked (e.g., if someone is experimenting
+// with other string implementations that get defined after this
+// file is included).  Save the current meaning now and use it
+// in the macro.
+typedef std::string _Check_string;
+#define CHECK_OP_LOG(name, op, val1, val2, log)                         \
+  while (@ac_google_namespace@::_Check_string* _result =                \
+         @ac_google_namespace@::Check##name##Impl(                      \
+             @ac_google_namespace@::GetReferenceableValue(val1),        \
+             @ac_google_namespace@::GetReferenceableValue(val2),        \
+             #val1 " " #op " " #val2))                                  \
+    log(__FILE__, __LINE__,                                             \
+        @ac_google_namespace@::CheckOpString(_result)).stream()
+#else
+// In optimized mode, use CheckOpString to hint to compiler that
+// the while condition is unlikely.
+#define CHECK_OP_LOG(name, op, val1, val2, log)                         \
+  while (@ac_google_namespace@::CheckOpString _result =                 \
+         @ac_google_namespace@::Check##name##Impl(                      \
+             @ac_google_namespace@::GetReferenceableValue(val1),        \
+             @ac_google_namespace@::GetReferenceableValue(val2),        \
+             #val1 " " #op " " #val2))                                  \
+    log(__FILE__, __LINE__, _result).stream()
+#endif  // STATIC_ANALYSIS, DCHECK_IS_ON()
+
+#if GOOGLE_STRIP_LOG <= 3
+#define CHECK_OP(name, op, val1, val2) \
+  CHECK_OP_LOG(name, op, val1, val2, @ac_google_namespace@::LogMessageFatal)
+#else
+#define CHECK_OP(name, op, val1, val2) \
+  CHECK_OP_LOG(name, op, val1, val2, @ac_google_namespace@::NullStreamFatal)
+#endif // STRIP_LOG <= 3
+
+// Equality/Inequality checks - compare two values, and log a FATAL message
+// including the two values when the result is not as expected.  The values
+// must have operator<<(ostream, ...) defined.
+//
+// You may append to the error message like so:
+//   CHECK_NE(1, 2) << ": The world must be ending!";
+//
+// We are very careful to ensure that each argument is evaluated exactly
+// once, and that anything which is legal to pass as a function argument is
+// legal here.  In particular, the arguments may be temporary expressions
+// which will end up being destroyed at the end of the apparent statement,
+// for example:
+//   CHECK_EQ(string("abc")[1], 'b');
+//
+// WARNING: These don't compile correctly if one of the arguments is a pointer
+// and the other is NULL. To work around this, simply static_cast NULL to the
+// type of the desired pointer.
+
+#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2)
+#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2)
+#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2)
+#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2)
+#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2)
+#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2)
+
+// Check that the input is non NULL.  This very useful in constructor
+// initializer lists.
+
+#define CHECK_NOTNULL(val) \
+  @ac_google_namespace@::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
+
+// Helper functions for string comparisons.
+// To avoid bloat, the definitions are in logging.cc.
+#define DECLARE_CHECK_STROP_IMPL(func, expected) \
+  GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \
+      const char* s1, const char* s2, const char* names);
+DECLARE_CHECK_STROP_IMPL(strcmp, true)
+DECLARE_CHECK_STROP_IMPL(strcmp, false)
+DECLARE_CHECK_STROP_IMPL(strcasecmp, true)
+DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
+#undef DECLARE_CHECK_STROP_IMPL
+
+// Helper macro for string comparisons.
+// Don't use this macro directly in your code, use CHECK_STREQ et al below.
+#define CHECK_STROP(func, op, expected, s1, s2) \
+  while (@ac_google_namespace@::CheckOpString _result = \
+         @ac_google_namespace@::Check##func##expected##Impl((s1), (s2), \
+                                     #s1 " " #op " " #s2)) \
+    LOG(FATAL) << *_result.str_
+
+
+// String (char*) equality/inequality checks.
+// CASE versions are case-insensitive.
+//
+// Note that "s1" and "s2" may be temporary strings which are destroyed
+// by the compiler at the end of the current "full expression"
+// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())).
+
+#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2)
+#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2)
+#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2)
+#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2)
+
+#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0])))
+#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0])))
+
+#define CHECK_DOUBLE_EQ(val1, val2)              \
+  do {                                           \
+    CHECK_LE((val1), (val2)+0.000000000000001L); \
+    CHECK_GE((val1), (val2)-0.000000000000001L); \
+  } while (0)
+
+#define CHECK_NEAR(val1, val2, margin)           \
+  do {                                           \
+    CHECK_LE((val1), (val2)+(margin));           \
+    CHECK_GE((val1), (val2)-(margin));           \
+  } while (0)
+
+// perror()..googly style!
+//
+// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and
+// CHECK equivalents with the addition that they postpend a description
+// of the current state of errno to their output lines.
+
+#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream()
+
+#define GOOGLE_PLOG(severity, counter)  \
+  @ac_google_namespace@::ErrnoLogMessage( \
+      __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, counter, \
+      &@ac_google_namespace@::LogMessage::SendToLog)
+
+#define PLOG_IF(severity, condition) \
+  !(condition) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & PLOG(severity)
+
+// A CHECK() macro that postpends errno if the condition is false. E.g.
+//
+// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... }
+#define PCHECK(condition)  \
+      PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
+              << "Check failed: " #condition " "
+
+// A CHECK() macro that lets you assert the success of a function that
+// returns -1 and sets errno in case of an error. E.g.
+//
+// CHECK_ERR(mkdir(path, 0700));
+//
+// or
+//
+// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename;
+#define CHECK_ERR(invocation)                                          \
+PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1))    \
+        << #invocation
+
+// Use macro expansion to create, for each use of LOG_EVERY_N(), static
+// variables with the __LINE__ expansion as part of the variable name.
+#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line)
+#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line
+
+#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__)
+#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__)
+
+#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
+  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+  ++LOG_OCCURRENCES; \
+  if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
+  if (LOG_OCCURRENCES_MOD_N == 1) \
+    @ac_google_namespace@::LogMessage( \
+        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
+        &what_to_do).stream()
+
+#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
+  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+  ++LOG_OCCURRENCES; \
+  if (condition && \
+      ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \
+    @ac_google_namespace@::LogMessage( \
+        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
+                 &what_to_do).stream()
+
+#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
+  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+  ++LOG_OCCURRENCES; \
+  if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
+  if (LOG_OCCURRENCES_MOD_N == 1) \
+    @ac_google_namespace@::ErrnoLogMessage( \
+        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
+        &what_to_do).stream()
+
+#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
+  static int LOG_OCCURRENCES = 0; \
+  if (LOG_OCCURRENCES <= n) \
+    ++LOG_OCCURRENCES; \
+  if (LOG_OCCURRENCES <= n) \
+    @ac_google_namespace@::LogMessage( \
+        __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
+        &what_to_do).stream()
+
+namespace glog_internal_namespace_ {
+template <bool>
+struct CompileAssert {
+};
+struct CrashReason;
+
+// Returns true if FailureSignalHandler is installed.
+// Needs to be exported since it's used by the signalhandler_unittest.
+GOOGLE_GLOG_DLL_DECL bool IsFailureSignalHandlerInstalled();
+}  // namespace glog_internal_namespace_
+
+#define LOG_EVERY_N(severity, n)                                        \
+  SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog)
+
+#define SYSLOG_EVERY_N(severity, n) \
+  SOME_KIND_OF_LOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToSyslogAndLog)
+
+#define PLOG_EVERY_N(severity, n) \
+  SOME_KIND_OF_PLOG_EVERY_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog)
+
+#define LOG_FIRST_N(severity, n) \
+  SOME_KIND_OF_LOG_FIRST_N(severity, (n), @ac_google_namespace@::LogMessage::SendToLog)
+
+#define LOG_IF_EVERY_N(severity, condition, n) \
+  SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), @ac_google_namespace@::LogMessage::SendToLog)
+
+// We want the special COUNTER value available for LOG_EVERY_X()'ed messages
+enum PRIVATE_Counter {COUNTER};
+
+#ifdef GLOG_NO_ABBREVIATED_SEVERITIES
+// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets
+// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us
+// to keep using this syntax, we define this macro to do the same thing
+// as COMPACT_GOOGLE_LOG_ERROR.
+#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
+#define SYSLOG_0 SYSLOG_ERROR
+#define LOG_TO_STRING_0 LOG_TO_STRING_ERROR
+// Needed for LOG_IS_ON(ERROR).
+const LogSeverity GLOG_0 = GLOG_ERROR;
+#else
+// Users may include windows.h after logging.h without
+// GLOG_NO_ABBREVIATED_SEVERITIES nor WIN32_LEAN_AND_MEAN.
+// For this case, we cannot detect if ERROR is defined before users
+// actually use ERROR. Let's make an undefined symbol to warn users.
+# define GLOG_ERROR_MSG ERROR_macro_is_defined_Define_GLOG_NO_ABBREVIATED_SEVERITIES_before_including_logging_h_See_the_document_for_detail
+# define COMPACT_GOOGLE_LOG_0 GLOG_ERROR_MSG
+# define SYSLOG_0 GLOG_ERROR_MSG
+# define LOG_TO_STRING_0 GLOG_ERROR_MSG
+# define GLOG_0 GLOG_ERROR_MSG
+#endif
+
+// Plus some debug-logging macros that get compiled to nothing for production
+
+#if DCHECK_IS_ON()
+
+#define DLOG(severity) LOG(severity)
+#define DVLOG(verboselevel) VLOG(verboselevel)
+#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
+#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n)
+#define DLOG_IF_EVERY_N(severity, condition, n) \
+  LOG_IF_EVERY_N(severity, condition, n)
+#define DLOG_ASSERT(condition) LOG_ASSERT(condition)
+
+// debug-only checking.  executed if DCHECK_IS_ON().
+#define DCHECK(condition) CHECK(condition)
+#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
+#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
+#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
+#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
+#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
+#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
+#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val)
+#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2)
+#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2)
+#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2)
+#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2)
+
+#else  // !DCHECK_IS_ON()
+
+#define DLOG(severity) \
+  true ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity)
+
+#define DVLOG(verboselevel) \
+  (true || !VLOG_IS_ON(verboselevel)) ?\
+    (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(INFO)
+
+#define DLOG_IF(severity, condition) \
+  (true || !(condition)) ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_EVERY_N(severity, n) \
+  true ? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_IF_EVERY_N(severity, condition, n) \
+  (true || !(condition))? (void) 0 : @ac_google_namespace@::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_ASSERT(condition) \
+  true ? (void) 0 : LOG_ASSERT(condition)
+
+// MSVC warning C4127: conditional expression is constant
+#define DCHECK(condition) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK(condition)
+
+#define DCHECK_EQ(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2)
+
+#define DCHECK_NE(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2)
+
+#define DCHECK_LE(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2)
+
+#define DCHECK_LT(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2)
+
+#define DCHECK_GE(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2)
+
+#define DCHECK_GT(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2)
+
+// You may see warnings in release mode if you don't use the return
+// value of DCHECK_NOTNULL. Please just use DCHECK for such cases.
+#define DCHECK_NOTNULL(val) (val)
+
+#define DCHECK_STREQ(str1, str2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2)
+
+#define DCHECK_STRCASEEQ(str1, str2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2)
+
+#define DCHECK_STRNE(str1, str2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2)
+
+#define DCHECK_STRCASENE(str1, str2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2)
+
+#endif  // DCHECK_IS_ON()
+
+// Log only in verbose mode.
+
+#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel))
+
+#define VLOG_IF(verboselevel, condition) \
+  LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel))
+
+#define VLOG_EVERY_N(verboselevel, n) \
+  LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n)
+
+#define VLOG_IF_EVERY_N(verboselevel, condition, n) \
+  LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n)
+
+namespace base_logging {
+
+// LogMessage::LogStream is a std::ostream backed by this streambuf.
+// This class ignores overflow and leaves two bytes at the end of the
+// buffer to allow for a '\n' and '\0'.
+class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf {
+ public:
+  // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\0'.
+  LogStreamBuf(char *buf, int len) {
+    setp(buf, buf + len - 2);
+  }
+
+  // This effectively ignores overflow.
+  virtual int_type overflow(int_type ch) {
+    return ch;
+  }
+
+  // Legacy public ostrstream method.
+  size_t pcount() const { return pptr() - pbase(); }
+  char* pbase() const { return std::streambuf::pbase(); }
+};
+
+}  // namespace base_logging
+
+//
+// This class more or less represents a particular log message.  You
+// create an instance of LogMessage and then stream stuff to it.
+// When you finish streaming to it, ~LogMessage is called and the
+// full message gets streamed to the appropriate destination.
+//
+// You shouldn't actually use LogMessage's constructor to log things,
+// though.  You should use the LOG() macro (and variants thereof)
+// above.
+class GOOGLE_GLOG_DLL_DECL LogMessage {
+public:
+  enum {
+    // Passing kNoLogPrefix for the line number disables the
+    // log-message prefix. Useful for using the LogMessage
+    // infrastructure as a printing utility. See also the --log_prefix
+    // flag for controlling the log-message prefix on an
+    // application-wide basis.
+    kNoLogPrefix = -1
+  };
+
+  // LogStream inherit from non-DLL-exported class (std::ostrstream)
+  // and VC++ produces a warning for this situation.
+  // However, MSDN says "C4275 can be ignored in Microsoft Visual C++
+  // 2005 if you are deriving from a type in the Standard C++ Library"
+  // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx
+  // Let's just ignore the warning.
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4275)
+#endif
+  class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream {
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+  public:
+    LogStream(char *buf, int len, int ctr)
+        : std::ostream(NULL),
+          streambuf_(buf, len),
+          ctr_(ctr),
+          self_(this) {
+      rdbuf(&streambuf_);
+    }
+
+    int ctr() const { return ctr_; }
+    void set_ctr(int ctr) { ctr_ = ctr; }
+    LogStream* self() const { return self_; }
+
+    // Legacy std::streambuf methods.
+    size_t pcount() const { return streambuf_.pcount(); }
+    char* pbase() const { return streambuf_.pbase(); }
+    char* str() const { return pbase(); }
+
+  private:
+    LogStream(const LogStream&);
+    LogStream& operator=(const LogStream&);
+    base_logging::LogStreamBuf streambuf_;
+    int ctr_;  // Counter hack (for the LOG_EVERY_X() macro)
+    LogStream *self_;  // Consistency check hack
+  };
+
+public:
+  // icc 8 requires this typedef to avoid an internal compiler error.
+  typedef void (LogMessage::*SendMethod)();
+
+  LogMessage(const char* file, int line, LogSeverity severity, int ctr,
+             SendMethod send_method);
+
+  // Two special constructors that generate reduced amounts of code at
+  // LOG call sites for common cases.
+
+  // Used for LOG(INFO): Implied are:
+  // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog.
+  //
+  // Using this constructor instead of the more complex constructor above
+  // saves 19 bytes per call site.
+  LogMessage(const char* file, int line);
+
+  // Used for LOG(severity) where severity != INFO.  Implied
+  // are: ctr = 0, send_method = &LogMessage::SendToLog
+  //
+  // Using this constructor instead of the more complex constructor above
+  // saves 17 bytes per call site.
+  LogMessage(const char* file, int line, LogSeverity severity);
+
+  // Constructor to log this message to a specified sink (if not NULL).
+  // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if
+  // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise.
+  LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink,
+             bool also_send_to_log);
+
+  // Constructor where we also give a vector<string> pointer
+  // for storing the messages (if the pointer is not NULL).
+  // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog.
+  LogMessage(const char* file, int line, LogSeverity severity,
+             std::vector<std::string>* outvec);
+
+  // Constructor where we also give a string pointer for storing the
+  // message (if the pointer is not NULL).  Implied are: ctr = 0,
+  // send_method = &LogMessage::WriteToStringAndLog.
+  LogMessage(const char* file, int line, LogSeverity severity,
+             std::string* message);
+
+  // A special constructor used for check failures
+  LogMessage(const char* file, int line, const CheckOpString& result);
+
+  ~LogMessage();
+
+  // Flush a buffered message to the sink set in the constructor.  Always
+  // called by the destructor, it may also be called from elsewhere if
+  // needed.  Only the first call is actioned; any later ones are ignored.
+  void Flush();
+
+  // An arbitrary limit on the length of a single log message.  This
+  // is so that streaming can be done more efficiently.
+  static const size_t kMaxLogMessageLen;
+
+  // Theses should not be called directly outside of logging.*,
+  // only passed as SendMethod arguments to other LogMessage methods:
+  void SendToLog();  // Actually dispatch to the logs
+  void SendToSyslogAndLog();  // Actually dispatch to syslog and the logs
+
+  // Call abort() or similar to perform LOG(FATAL) crash.
+  static void @ac_cv___attribute___noreturn@ Fail();
+
+  std::ostream& stream();
+
+  int preserved_errno() const;
+
+  // Must be called without the log_mutex held.  (L < log_mutex)
+  static int64 num_messages(int severity);
+
+  struct LogMessageData;
+
+private:
+  // Fully internal SendMethod cases:
+  void SendToSinkAndLog();  // Send to sink if provided and dispatch to the logs
+  void SendToSink();  // Send to sink if provided, do nothing otherwise.
+
+  // Write to string if provided and dispatch to the logs.
+  void WriteToStringAndLog();
+
+  void SaveOrSendToLog();  // Save to stringvec if provided, else to logs
+
+  void Init(const char* file, int line, LogSeverity severity,
+            void (LogMessage::*send_method)());
+
+  // Used to fill in crash information during LOG(FATAL) failures.
+  void RecordCrashReason(glog_internal_namespace_::CrashReason* reason);
+
+  // Counts of messages sent at each priority:
+  static int64 num_messages_[NUM_SEVERITIES];  // under log_mutex
+
+  // We keep the data in a separate struct so that each instance of
+  // LogMessage uses less stack space.
+  LogMessageData* allocated_;
+  LogMessageData* data_;
+
+  friend class LogDestination;
+
+  LogMessage(const LogMessage&);
+  void operator=(const LogMessage&);
+};
+
+// This class happens to be thread-hostile because all instances share
+// a single data buffer, but since it can only be created just before
+// the process dies, we don't worry so much.
+class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage {
+ public:
+  LogMessageFatal(const char* file, int line);
+  LogMessageFatal(const char* file, int line, const CheckOpString& result);
+  @ac_cv___attribute___noreturn@ ~LogMessageFatal();
+};
+
+// A non-macro interface to the log facility; (useful
+// when the logging level is not a compile-time constant).
+inline void LogAtLevel(int const severity, std::string const &msg) {
+  LogMessage(__FILE__, __LINE__, severity).stream() << msg;
+}
+
+// A macro alternative of LogAtLevel. New code may want to use this
+// version since there are two advantages: 1. this version outputs the
+// file name and the line number where this macro is put like other
+// LOG macros, 2. this macro can be used as C++ stream.
+#define LOG_AT_LEVEL(severity) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream()
+
+// Check if it's compiled in C++11 mode.
+//
+// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least
+// gcc-4.7 and clang-3.1 (2011-12-13).  __cplusplus was defined to 1
+// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is
+// defined according to the language version in effect thereafter.
+// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite
+// reasonably good C++11 support, so we set LANG_CXX for it and
+// newer versions (_MSC_VER >= 1900).
+#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
+     (defined(_MSC_VER) && _MSC_VER >= 1900))
+// Helper for CHECK_NOTNULL().
+//
+// In C++11, all cases can be handled by a single function. Since the value
+// category of the argument is preserved (also for rvalue references),
+// member initializer lists like the one below will compile correctly:
+//
+//   Foo()
+//     : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {}
+template <typename T>
+T CheckNotNull(const char* file, int line, const char* names, T&& t) {
+ if (t == nullptr) {
+   LogMessageFatal(file, line, new std::string(names));
+ }
+ return std::forward<T>(t);
+}
+
+#else
+
+// A small helper for CHECK_NOTNULL().
+template <typename T>
+T* CheckNotNull(const char *file, int line, const char *names, T* t) {
+  if (t == NULL) {
+    LogMessageFatal(file, line, new std::string(names));
+  }
+  return t;
+}
+#endif
+
+// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This
+// only works if ostream is a LogStream. If the ostream is not a
+// LogStream you'll get an assert saying as much at runtime.
+GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os,
+                                              const PRIVATE_Counter&);
+
+
+// Derived class for PLOG*() above.
+class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage {
+ public:
+
+  ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr,
+                  void (LogMessage::*send_method)());
+
+  // Postpends ": strerror(errno) [errno]".
+  ~ErrnoLogMessage();
+
+ private:
+  ErrnoLogMessage(const ErrnoLogMessage&);
+  void operator=(const ErrnoLogMessage&);
+};
+
+
+// This class is used to explicitly ignore values in the conditional
+// logging macros.  This avoids compiler warnings like "value computed
+// is not used" and "statement has no effect".
+
+class GOOGLE_GLOG_DLL_DECL LogMessageVoidify {
+ public:
+  LogMessageVoidify() { }
+  // This has to be an operator with a precedence lower than << but
+  // higher than ?:
+  void operator&(std::ostream&) { }
+};
+
+
+// Flushes all log files that contains messages that are at least of
+// the specified severity level.  Thread-safe.
+GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity);
+
+// Flushes all log files that contains messages that are at least of
+// the specified severity level. Thread-hostile because it ignores
+// locking -- used for catastrophic failures.
+GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity);
+
+//
+// Set the destination to which a particular severity level of log
+// messages is sent.  If base_filename is "", it means "don't log this
+// severity".  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity,
+                                            const char* base_filename);
+
+//
+// Set the basename of the symlink to the latest log file at a given
+// severity.  If symlink_basename is empty, do not make a symlink.  If
+// you don't call this function, the symlink basename is the
+// invocation name of the program.  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity,
+                                        const char* symlink_basename);
+
+//
+// Used to send logs to some other kind of destination
+// Users should subclass LogSink and override send to do whatever they want.
+// Implementations must be thread-safe because a shared instance will
+// be called from whichever thread ran the LOG(XXX) line.
+class GOOGLE_GLOG_DLL_DECL LogSink {
+ public:
+  virtual ~LogSink();
+
+  // Sink's logging logic (message_len is such as to exclude '\n' at the end).
+  // This method can't use LOG() or CHECK() as logging system mutex(s) are held
+  // during this call.
+  virtual void send(LogSeverity severity, const char* full_filename,
+                    const char* base_filename, int line,
+                    const struct ::tm* tm_time,
+                    const char* message, size_t message_len) = 0;
+
+  // Redefine this to implement waiting for
+  // the sink's logging logic to complete.
+  // It will be called after each send() returns,
+  // but before that LogMessage exits or crashes.
+  // By default this function does nothing.
+  // Using this function one can implement complex logic for send()
+  // that itself involves logging; and do all this w/o causing deadlocks and
+  // inconsistent rearrangement of log messages.
+  // E.g. if a LogSink has thread-specific actions, the send() method
+  // can simply add the message to a queue and wake up another thread that
+  // handles real logging while itself making some LOG() calls;
+  // WaitTillSent() can be implemented to wait for that logic to complete.
+  // See our unittest for an example.
+  virtual void WaitTillSent();
+
+  // Returns the normal text output of the log message.
+  // Can be useful to implement send().
+  static std::string ToString(LogSeverity severity, const char* file, int line,
+                              const struct ::tm* tm_time,
+                              const char* message, size_t message_len);
+};
+
+// Add or remove a LogSink as a consumer of logging data.  Thread-safe.
+GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination);
+GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination);
+
+//
+// Specify an "extension" added to the filename specified via
+// SetLogDestination.  This applies to all severity levels.  It's
+// often used to append the port we're listening on to the logfile
+// name.  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension(
+    const char* filename_extension);
+
+//
+// Make it so that all log messages of at least a particular severity
+// are logged to stderr (in addition to logging to the usual log
+// file(s)).  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity);
+
+//
+// Make it so that all log messages go only to stderr.  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void LogToStderr();
+
+//
+// Make it so that all log messages of at least a particular severity are
+// logged via email to a list of addresses (in addition to logging to the
+// usual log file(s)).  The list of addresses is just a string containing
+// the email addresses to send to (separated by spaces, say).  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity,
+                                          const char* addresses);
+
+// A simple function that sends email. dest is a commma-separated
+// list of addressess.  Thread-safe.
+GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest,
+                                    const char *subject, const char *body);
+
+GOOGLE_GLOG_DLL_DECL const std::vector<std::string>& GetLoggingDirectories();
+
+// For tests only:  Clear the internal [cached] list of logging directories to
+// force a refresh the next time GetLoggingDirectories is called.
+// Thread-hostile.
+void TestOnly_ClearLoggingDirectoriesList();
+
+// Returns a set of existing temporary directories, which will be a
+// subset of the directories returned by GetLogginDirectories().
+// Thread-safe.
+GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories(
+    std::vector<std::string>* list);
+
+// Print any fatal message again -- useful to call from signal handler
+// so that the last thing in the output is the fatal message.
+// Thread-hostile, but a race is unlikely.
+GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage();
+
+// Truncate a log file that may be the append-only output of multiple
+// processes and hence can't simply be renamed/reopened (typically a
+// stdout/stderr).  If the file "path" is > "limit" bytes, copy the
+// last "keep" bytes to offset 0 and truncate the rest. Since we could
+// be racing with other writers, this approach has the potential to
+// lose very small amounts of data. For security, only follow symlinks
+// if the path is /proc/self/fd/*
+GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path,
+                                          int64 limit, int64 keep);
+
+// Truncate stdout and stderr if they are over the value specified by
+// --max_log_size; keep the final 1MB.  This function has the same
+// race condition as TruncateLogFile.
+GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr();
+
+// Return the string representation of the provided LogSeverity level.
+// Thread-safe.
+GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity);
+
+// ---------------------------------------------------------------------
+// Implementation details that are not useful to most clients
+// ---------------------------------------------------------------------
+
+// A Logger is the interface used by logging modules to emit entries
+// to a log.  A typical implementation will dump formatted data to a
+// sequence of files.  We also provide interfaces that will forward
+// the data to another thread so that the invoker never blocks.
+// Implementations should be thread-safe since the logging system
+// will write to them from multiple threads.
+
+namespace base {
+
+class GOOGLE_GLOG_DLL_DECL Logger {
+ public:
+  virtual ~Logger();
+
+  // Writes "message[0,message_len-1]" corresponding to an event that
+  // occurred at "timestamp".  If "force_flush" is true, the log file
+  // is flushed immediately.
+  //
+  // The input message has already been formatted as deemed
+  // appropriate by the higher level logging facility.  For example,
+  // textual log messages already contain timestamps, and the
+  // file:linenumber header.
+  virtual void Write(bool force_flush,
+                     time_t timestamp,
+                     const char* message,
+                     int message_len) = 0;
+
+  // Flush any buffered messages
+  virtual void Flush() = 0;
+
+  // Get the current LOG file size.
+  // The returned value is approximate since some
+  // logged data may not have been flushed to disk yet.
+  virtual uint32 LogSize() = 0;
+};
+
+// Get the logger for the specified severity level.  The logger
+// remains the property of the logging module and should not be
+// deleted by the caller.  Thread-safe.
+extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level);
+
+// Set the logger for the specified severity level.  The logger
+// becomes the property of the logging module and should not
+// be deleted by the caller.  Thread-safe.
+extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger);
+
+}
+
+// glibc has traditionally implemented two incompatible versions of
+// strerror_r(). There is a poorly defined convention for picking the
+// version that we want, but it is not clear whether it even works with
+// all versions of glibc.
+// So, instead, we provide this wrapper that automatically detects the
+// version that is in use, and then implements POSIX semantics.
+// N.B. In addition to what POSIX says, we also guarantee that "buf" will
+// be set to an empty string, if this function failed. This means, in most
+// cases, you do not need to check the error code and you can directly
+// use the value of "buf". It will never have an undefined value.
+// DEPRECATED: Use StrError(int) instead.
+GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len);
+
+// A thread-safe replacement for strerror(). Returns a string describing the
+// given POSIX error code.
+GOOGLE_GLOG_DLL_DECL std::string StrError(int err);
+
+// A class for which we define operator<<, which does nothing.
+class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
+ public:
+  // Initialize the LogStream so the messages can be written somewhere
+  // (they'll never be actually displayed). This will be needed if a
+  // NullStream& is implicitly converted to LogStream&, in which case
+  // the overloaded NullStream::operator<< will not be invoked.
+  NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { }
+  NullStream(const char* /*file*/, int /*line*/,
+             const CheckOpString& /*result*/) :
+      LogMessage::LogStream(message_buffer_, 1, 0) { }
+  NullStream &stream() { return *this; }
+ private:
+  // A very short buffer for messages (which we discard anyway). This
+  // will be needed if NullStream& converted to LogStream& (e.g. as a
+  // result of a conditional expression).
+  char message_buffer_[2];
+};
+
+// Do nothing. This operator is inline, allowing the message to be
+// compiled away. The message will not be compiled away if we do
+// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when
+// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly
+// converted to LogStream and the message will be computed and then
+// quietly discarded.
+template<class T>
+inline NullStream& operator<<(NullStream &str, const T &) { return str; }
+
+// Similar to NullStream, but aborts the program (without stack
+// trace), like LogMessageFatal.
+class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream {
+ public:
+  NullStreamFatal() { }
+  NullStreamFatal(const char* file, int line, const CheckOpString& result) :
+      NullStream(file, line, result) { }
+  @ac_cv___attribute___noreturn@ ~NullStreamFatal() throw () { _exit(1); }
+};
+
+// Install a signal handler that will dump signal information and a stack
+// trace when the program crashes on certain signals.  We'll install the
+// signal handler for the following signals.
+//
+// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM.
+//
+// By default, the signal handler will write the failure dump to the
+// standard error.  You can customize the destination by installing your
+// own writer function by InstallFailureWriter() below.
+//
+// Note on threading:
+//
+// The function should be called before threads are created, if you want
+// to use the failure signal handler for all threads.  The stack trace
+// will be shown only for the thread that receives the signal.  In other
+// words, stack traces of other threads won't be shown.
+GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler();
+
+// Installs a function that is used for writing the failure dump.  "data"
+// is the pointer to the beginning of a message to be written, and "size"
+// is the size of the message.  You should not expect the data is
+// terminated with '\0'.
+GOOGLE_GLOG_DLL_DECL void InstallFailureWriter(
+    void (*writer)(const char* data, int size));
+
+@ac_google_end_namespace@
+
+#endif // _LOGGING_H_
diff --git a/third_party/google-glog/src/glog/raw_logging.h.in b/third_party/google-glog/src/glog/raw_logging.h.in
new file mode 100644
index 0000000..fa17057
--- /dev/null
+++ b/third_party/google-glog/src/glog/raw_logging.h.in
@@ -0,0 +1,185 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Maxim Lifantsev
+//
+// Thread-safe logging routines that do not allocate any memory or
+// acquire any locks, and can therefore be used by low-level memory
+// allocation and synchronization code.
+
+#ifndef BASE_RAW_LOGGING_H_
+#define BASE_RAW_LOGGING_H_
+
+#include <time.h>
+
+@ac_google_start_namespace@
+
+#include "glog/log_severity.h"
+#include "glog/vlog_is_on.h"
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+#   define GOOGLE_GLOG_DLL_DECL  __declspec(dllimport)
+# else
+#   define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// This is similar to LOG(severity) << format... and VLOG(level) << format..,
+// but
+// * it is to be used ONLY by low-level modules that can't use normal LOG()
+// * it is desiged to be a low-level logger that does not allocate any
+//   memory and does not need any locks, hence:
+// * it logs straight and ONLY to STDERR w/o buffering
+// * it uses an explicit format and arguments list
+// * it will silently chop off really long message strings
+// Usage example:
+//   RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
+//   RAW_VLOG(3, "status is %i", status);
+// These will print an almost standard log lines like this to stderr only:
+//   E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
+//   I0821 211317 file.cc:142] RAW: status is 20
+#define RAW_LOG(severity, ...) \
+  do { \
+    switch (@ac_google_namespace@::GLOG_ ## severity) {  \
+      case 0: \
+        RAW_LOG_INFO(__VA_ARGS__); \
+        break; \
+      case 1: \
+        RAW_LOG_WARNING(__VA_ARGS__); \
+        break; \
+      case 2: \
+        RAW_LOG_ERROR(__VA_ARGS__); \
+        break; \
+      case 3: \
+        RAW_LOG_FATAL(__VA_ARGS__); \
+        break; \
+      default: \
+        break; \
+    } \
+  } while (0)
+
+// The following STRIP_LOG testing is performed in the header file so that it's
+// possible to completely compile out the logging code and the log messages.
+#if STRIP_LOG == 0
+#define RAW_VLOG(verboselevel, ...) \
+  do { \
+    if (VLOG_IS_ON(verboselevel)) { \
+      RAW_LOG_INFO(__VA_ARGS__); \
+    } \
+  } while (0)
+#else
+#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG == 0
+
+#if STRIP_LOG == 0
+#define RAW_LOG_INFO(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_INFO, \
+                                   __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_INFO(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG == 0
+
+#if STRIP_LOG <= 1
+#define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_WARNING,   \
+                                      __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_WARNING(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG <= 1
+
+#if STRIP_LOG <= 2
+#define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_ERROR,       \
+                                    __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_ERROR(...) @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG <= 2
+
+#if STRIP_LOG <= 3
+#define RAW_LOG_FATAL(...) @ac_google_namespace@::RawLog__(@ac_google_namespace@::GLOG_FATAL,       \
+                                    __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_FATAL(...) \
+  do { \
+    @ac_google_namespace@::RawLogStub__(0, __VA_ARGS__);        \
+    exit(1); \
+  } while (0)
+#endif // STRIP_LOG <= 3
+
+// Similar to CHECK(condition) << message,
+// but for low-level modules: we use only RAW_LOG that does not allocate memory.
+// We do not want to provide args list here to encourage this usage:
+//   if (!cond)  RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
+// so that the args are not computed when not needed.
+#define RAW_CHECK(condition, message)                                   \
+  do {                                                                  \
+    if (!(condition)) {                                                 \
+      RAW_LOG(FATAL, "Check %s failed: %s", #condition, message);       \
+    }                                                                   \
+  } while (0)
+
+// Debug versions of RAW_LOG and RAW_CHECK
+#ifndef NDEBUG
+
+#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
+#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
+
+#else  // NDEBUG
+
+#define RAW_DLOG(severity, ...)                                 \
+  while (false)                                                 \
+    RAW_LOG(severity, __VA_ARGS__)
+#define RAW_DCHECK(condition, message) \
+  while (false) \
+    RAW_CHECK(condition, message)
+
+#endif  // NDEBUG
+
+// Stub log function used to work around for unused variable warnings when
+// building with STRIP_LOG > 0.
+static inline void RawLogStub__(int /* ignored */, ...) {
+}
+
+// Helper function to implement RAW_LOG and RAW_VLOG
+// Logs format... at "severity" level, reporting it
+// as called from file:line.
+// This does not allocate memory or acquire locks.
+GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity,
+                                   const char* file,
+                                   int line,
+                                   const char* format, ...)
+   @ac_cv___attribute___printf_4_5@;
+
+// Hack to propagate time information into this module so that
+// this module does not have to directly call localtime_r(),
+// which could allocate memory.
+GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs);
+
+@ac_google_end_namespace@
+
+#endif  // BASE_RAW_LOGGING_H_
diff --git a/third_party/google-glog/src/glog/stl_logging.h.in b/third_party/google-glog/src/glog/stl_logging.h.in
new file mode 100644
index 0000000..600945d
--- /dev/null
+++ b/third_party/google-glog/src/glog/stl_logging.h.in
@@ -0,0 +1,220 @@
+// Copyright (c) 2003, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Stream output operators for STL containers; to be used for logging *only*.
+// Inclusion of this file lets you do:
+//
+// list<string> x;
+// LOG(INFO) << "data: " << x;
+// vector<int> v1, v2;
+// CHECK_EQ(v1, v2);
+//
+// If you want to use this header file with hash maps or slist, you
+// need to define macros before including this file:
+//
+// - GLOG_STL_LOGGING_FOR_UNORDERED     - <unordered_map> and <unordered_set>
+// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)>
+// - GLOG_STL_LOGGING_FOR_EXT_HASH      - <ext/hash_(map|set)>
+// - GLOG_STL_LOGGING_FOR_EXT_SLIST     - <ext/slist>
+//
+
+#ifndef UTIL_GTL_STL_LOGGING_INL_H_
+#define UTIL_GTL_STL_LOGGING_INL_H_
+
+#if !@ac_cv_cxx_using_operator@
+# error We do not support stl_logging for this compiler
+#endif
+
+#include <deque>
+#include <list>
+#include <map>
+#include <ostream>
+#include <set>
+#include <utility>
+#include <vector>
+
+#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
+# include <unordered_map>
+# include <unordered_set>
+#endif
+
+#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
+# include <tr1/unordered_map>
+# include <tr1/unordered_set>
+#endif
+
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+# include <ext/hash_set>
+# include <ext/hash_map>
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
+# include <ext/slist>
+#endif
+
+// Forward declare these two, and define them after all the container streams
+// operators so that we can recurse from pair -> container -> container -> pair
+// properly.
+template<class First, class Second>
+std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p);
+
+@ac_google_start_namespace@
+
+template<class Iter>
+void PrintSequence(std::ostream& out, Iter begin, Iter end);
+
+@ac_google_end_namespace@
+
+#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
+template<class T1, class T2> \
+inline std::ostream& operator<<(std::ostream& out, \
+                                const Sequence<T1, T2>& seq) { \
+  @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \
+  return out; \
+}
+
+OUTPUT_TWO_ARG_CONTAINER(std::vector)
+OUTPUT_TWO_ARG_CONTAINER(std::deque)
+OUTPUT_TWO_ARG_CONTAINER(std::list)
+#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
+OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist)
+#endif
+
+#undef OUTPUT_TWO_ARG_CONTAINER
+
+#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \
+template<class T1, class T2, class T3> \
+inline std::ostream& operator<<(std::ostream& out, \
+                                const Sequence<T1, T2, T3>& seq) { \
+  @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \
+  return out; \
+}
+
+OUTPUT_THREE_ARG_CONTAINER(std::set)
+OUTPUT_THREE_ARG_CONTAINER(std::multiset)
+
+#undef OUTPUT_THREE_ARG_CONTAINER
+
+#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \
+template<class T1, class T2, class T3, class T4> \
+inline std::ostream& operator<<(std::ostream& out, \
+                                const Sequence<T1, T2, T3, T4>& seq) { \
+  @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \
+  return out; \
+}
+
+OUTPUT_FOUR_ARG_CONTAINER(std::map)
+OUTPUT_FOUR_ARG_CONTAINER(std::multimap)
+#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
+OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
+OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
+OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set)
+OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset)
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set)
+OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset)
+#endif
+
+#undef OUTPUT_FOUR_ARG_CONTAINER
+
+#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \
+template<class T1, class T2, class T3, class T4, class T5> \
+inline std::ostream& operator<<(std::ostream& out, \
+                                const Sequence<T1, T2, T3, T4, T5>& seq) { \
+  @ac_google_namespace@::PrintSequence(out, seq.begin(), seq.end()); \
+  return out; \
+}
+
+#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
+OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
+OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
+OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map)
+OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap)
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map)
+OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap)
+#endif
+
+#undef OUTPUT_FIVE_ARG_CONTAINER
+
+template<class First, class Second>
+inline std::ostream& operator<<(std::ostream& out,
+                                const std::pair<First, Second>& p) {
+  out << '(' << p.first << ", " << p.second << ')';
+  return out;
+}
+
+@ac_google_start_namespace@
+
+template<class Iter>
+inline void PrintSequence(std::ostream& out, Iter begin, Iter end) {
+  // Output at most 100 elements -- appropriate if used for logging.
+  for (int i = 0; begin != end && i < 100; ++i, ++begin) {
+    if (i > 0) out << ' ';
+    out << *begin;
+  }
+  if (begin != end) {
+    out << " ...";
+  }
+}
+
+@ac_google_end_namespace@
+
+// Note that this is technically undefined behavior! We are adding things into
+// the std namespace for a reason though -- we are providing new operations on
+// types which are themselves defined with this namespace. Without this, these
+// operator overloads cannot be found via ADL. If these definitions are not
+// found via ADL, they must be #included before they're used, which requires
+// this header to be included before apparently independent other headers.
+//
+// For example, base/logging.h defines various template functions to implement
+// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails.
+// It does so via the function template MakeCheckOpValueString:
+//   template<class T>
+//   void MakeCheckOpValueString(strstream* ss, const T& v) {
+//     (*ss) << v;
+//   }
+// Because 'glog/logging.h' is included before 'glog/stl_logging.h',
+// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only
+// find these operator definitions via ADL.
+//
+// Even this solution has problems -- it may pull unintended operators into the
+// namespace as well, allowing them to also be found via ADL, and creating code
+// that only works with a particular order of includes. Long term, we need to
+// move all of the *definitions* into namespace std, bet we need to ensure no
+// one references them first. This lets us take that step. We cannot define them
+// in both because that would create ambiguous overloads when both are found.
+namespace std { using ::operator<<; }
+
+#endif  // UTIL_GTL_STL_LOGGING_INL_H_
diff --git a/third_party/google-glog/src/glog/vlog_is_on.h.in b/third_party/google-glog/src/glog/vlog_is_on.h.in
new file mode 100644
index 0000000..3f4c4a3
--- /dev/null
+++ b/third_party/google-glog/src/glog/vlog_is_on.h.in
@@ -0,0 +1,129 @@
+// Copyright (c) 1999, 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney and many others
+//
+// Defines the VLOG_IS_ON macro that controls the variable-verbosity
+// conditional logging.
+//
+// It's used by VLOG and VLOG_IF in logging.h
+// and by RAW_VLOG in raw_logging.h to trigger the logging.
+//
+// It can also be used directly e.g. like this:
+//   if (VLOG_IS_ON(2)) {
+//     // do some logging preparation and logging
+//     // that can't be accomplished e.g. via just VLOG(2) << ...;
+//   }
+//
+// The truth value that VLOG_IS_ON(level) returns is determined by 
+// the three verbosity level flags:
+//   --v=<n>  Gives the default maximal active V-logging level;
+//            0 is the default.
+//            Normally positive values are used for V-logging levels.
+//   --vmodule=<str>  Gives the per-module maximal V-logging levels to override
+//                    the value given by --v.
+//                    E.g. "my_module=2,foo*=3" would change the logging level
+//                    for all code in source files "my_module.*" and "foo*.*"
+//                    ("-inl" suffixes are also disregarded for this matching).
+//
+// SetVLOGLevel helper function is provided to do limited dynamic control over
+// V-logging by overriding the per-module settings given via --vmodule flag.
+//
+// CAVEAT: --vmodule functionality is not available in non gcc compilers.
+//
+
+#ifndef BASE_VLOG_IS_ON_H_
+#define BASE_VLOG_IS_ON_H_
+
+#include "glog/log_severity.h"
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+#   define GOOGLE_GLOG_DLL_DECL  __declspec(dllimport)
+# else
+#   define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+#if defined(__GNUC__)
+// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
+// (Normally) the first time every VLOG_IS_ON(n) site is hit,
+// we determine what variable will dynamically control logging at this site:
+// it's either FLAGS_v or an appropriate internal variable
+// matching the current source file that represents results of
+// parsing of --vmodule flag and/or SetVLOGLevel calls.
+#define VLOG_IS_ON(verboselevel)                                \
+  __extension__  \
+  ({ static @ac_google_namespace@::int32* vlocal__ = &@ac_google_namespace@::kLogSiteUninitialized;           \
+     @ac_google_namespace@::int32 verbose_level__ = (verboselevel);                    \
+     (*vlocal__ >= verbose_level__) &&                          \
+     ((vlocal__ != &@ac_google_namespace@::kLogSiteUninitialized) ||                   \
+      (@ac_google_namespace@::InitVLOG3__(&vlocal__, &FLAGS_v,                         \
+                   __FILE__, verbose_level__))); })
+#else
+// GNU extensions not available, so we do not support --vmodule.
+// Dynamic value of FLAGS_v always controls the logging level.
+#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
+#endif
+
+// Set VLOG(_IS_ON) level for module_pattern to log_level.
+// This lets us dynamically control what is normally set by the --vmodule flag.
+// Returns the level that previously applied to module_pattern.
+// NOTE: To change the log level for VLOG(_IS_ON) sites
+//	 that have already executed after/during InitGoogleLogging,
+//	 one needs to supply the exact --vmodule pattern that applied to them.
+//       (If no --vmodule pattern applied to them
+//       the value of FLAGS_v will continue to control them.)
+extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,
+                                             int log_level);
+
+// Various declarations needed for VLOG_IS_ON above: =========================
+
+// Special value used to indicate that a VLOG_IS_ON site has not been
+// initialized.  We make this a large value, so the common-case check
+// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition
+// passes in such cases and InitVLOG3__ is then triggered.
+extern @ac_google_namespace@::int32 kLogSiteUninitialized;
+
+// Helper routine which determines the logging info for a particalur VLOG site.
+//   site_flag     is the address of the site-local pointer to the controlling
+//                 verbosity level
+//   site_default  is the default to use for *site_flag
+//   fname         is the current source file name
+//   verbose_level is the argument to VLOG_IS_ON
+// We will return the return value for VLOG_IS_ON
+// and if possible set *site_flag appropriately.
+extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
+    @ac_google_namespace@::int32** site_flag,
+    @ac_google_namespace@::int32* site_default,
+    const char* fname,
+    @ac_google_namespace@::int32 verbose_level);
+
+#endif  // BASE_VLOG_IS_ON_H_
diff --git a/third_party/google-glog/src/googletest.h b/third_party/google-glog/src/googletest.h
new file mode 100644
index 0000000..49ddbc0
--- /dev/null
+++ b/third_party/google-glog/src/googletest.h
@@ -0,0 +1,606 @@
+// Copyright (c) 2009, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Shinichiro Hamaji
+//   (based on googletest: http://code.google.com/p/googletest/)
+
+#ifdef GOOGLETEST_H__
+#error You must not include this file twice.
+#endif
+#define GOOGLETEST_H__
+
+#include "utilities.h"
+
+#include <ctype.h>
+#include <setjmp.h>
+#include <time.h>
+
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "base/commandlineflags.h"
+
+using std::map;
+using std::string;
+using std::vector;
+
+_START_GOOGLE_NAMESPACE_
+
+extern GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)();
+
+_END_GOOGLE_NAMESPACE_
+
+#undef GOOGLE_GLOG_DLL_DECL
+#define GOOGLE_GLOG_DLL_DECL
+
+static inline string GetTempDir() {
+#ifndef OS_WINDOWS
+  return "/tmp";
+#else
+  char tmp[MAX_PATH];
+  GetTempPathA(MAX_PATH, tmp);
+  return tmp;
+#endif
+}
+
+#if defined(OS_WINDOWS) && defined(_MSC_VER) && !defined(TEST_SRC_DIR)
+// The test will run in glog/vsproject/<project name>
+// (e.g., glog/vsproject/logging_unittest).
+static const char TEST_SRC_DIR[] = "../..";
+#elif !defined(TEST_SRC_DIR)
+# warning TEST_SRC_DIR should be defined in config.h
+static const char TEST_SRC_DIR[] = ".";
+#endif
+
+static const uint32_t PTR_TEST_VALUE = 0x12345678;
+
+DEFINE_string(test_tmpdir, GetTempDir(), "Dir we use for temp files");
+DEFINE_string(test_srcdir, TEST_SRC_DIR,
+              "Source-dir root, needed to find glog_unittest_flagfile");
+DEFINE_bool(run_benchmark, false, "If true, run benchmarks");
+#ifdef NDEBUG
+DEFINE_int32(benchmark_iters, 100000000, "Number of iterations per benchmark");
+#else
+DEFINE_int32(benchmark_iters, 100000, "Number of iterations per benchmark");
+#endif
+
+#ifdef HAVE_LIB_GTEST
+# include <gtest/gtest.h>
+// Use our ASSERT_DEATH implementation.
+# undef ASSERT_DEATH
+# undef ASSERT_DEBUG_DEATH
+using testing::InitGoogleTest;
+#else
+
+_START_GOOGLE_NAMESPACE_
+
+void InitGoogleTest(int*, char**);
+
+void InitGoogleTest(int*, char**) {}
+
+// The following is some bare-bones testing infrastructure
+
+#define EXPECT_TRUE(cond)                               \
+  do {                                                  \
+    if (!(cond)) {                                      \
+      fprintf(stderr, "Check failed: %s\n", #cond);     \
+      exit(1);                                          \
+    }                                                   \
+  } while (0)
+
+#define EXPECT_FALSE(cond)  EXPECT_TRUE(!(cond))
+
+#define EXPECT_OP(op, val1, val2)                                       \
+  do {                                                                  \
+    if (!((val1) op (val2))) {                                          \
+      fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
+      exit(1);                                                          \
+    }                                                                   \
+  } while (0)
+
+#define EXPECT_EQ(val1, val2)  EXPECT_OP(==, val1, val2)
+#define EXPECT_NE(val1, val2)  EXPECT_OP(!=, val1, val2)
+#define EXPECT_GT(val1, val2)  EXPECT_OP(>, val1, val2)
+#define EXPECT_LT(val1, val2)  EXPECT_OP(<, val1, val2)
+
+#define EXPECT_NAN(arg)                                         \
+  do {                                                          \
+    if (!isnan(arg)) {                                          \
+      fprintf(stderr, "Check failed: isnan(%s)\n", #arg);       \
+      exit(1);                                                  \
+    }                                                           \
+  } while (0)
+
+#define EXPECT_INF(arg)                                         \
+  do {                                                          \
+    if (!isinf(arg)) {                                          \
+      fprintf(stderr, "Check failed: isinf(%s)\n", #arg);       \
+      exit(1);                                                  \
+    }                                                           \
+  } while (0)
+
+#define EXPECT_DOUBLE_EQ(val1, val2)                                    \
+  do {                                                                  \
+    if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) {         \
+      fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2);        \
+      exit(1);                                                          \
+    }                                                                   \
+  } while (0)
+
+#define EXPECT_STREQ(val1, val2)                                        \
+  do {                                                                  \
+    if (strcmp((val1), (val2)) != 0) {                                  \
+      fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2);   \
+      exit(1);                                                          \
+    }                                                                   \
+  } while (0)
+
+vector<void (*)()> g_testlist;  // the tests to run
+
+#define TEST(a, b)                                      \
+  struct Test_##a##_##b {                               \
+    Test_##a##_##b() { g_testlist.push_back(&Run); }    \
+    static void Run() { FlagSaver fs; RunTest(); }      \
+    static void RunTest();                              \
+  };                                                    \
+  static Test_##a##_##b g_test_##a##_##b;               \
+  void Test_##a##_##b::RunTest()
+
+
+static inline int RUN_ALL_TESTS() {
+  vector<void (*)()>::const_iterator it;
+  for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
+    (*it)();
+  }
+  fprintf(stderr, "Passed %d tests\n\nPASS\n", (int)g_testlist.size());
+  return 0;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#endif  // ! HAVE_LIB_GTEST
+
+_START_GOOGLE_NAMESPACE_
+
+static bool g_called_abort;
+static jmp_buf g_jmp_buf;
+static inline void CalledAbort() {
+  g_called_abort = true;
+  longjmp(g_jmp_buf, 1);
+}
+
+#ifdef OS_WINDOWS
+// TODO(hamaji): Death test somehow doesn't work in Windows.
+#define ASSERT_DEATH(fn, msg)
+#else
+#define ASSERT_DEATH(fn, msg)                                           \
+  do {                                                                  \
+    g_called_abort = false;                                             \
+    /* in logging.cc */                                                 \
+    void (*original_logging_fail_func)() = g_logging_fail_func;         \
+    g_logging_fail_func = &CalledAbort;                                 \
+    if (!setjmp(g_jmp_buf)) fn;                                         \
+    /* set back to their default */                                     \
+    g_logging_fail_func = original_logging_fail_func;                   \
+    if (!g_called_abort) {                                              \
+      fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn);      \
+      exit(1);                                                          \
+    }                                                                   \
+  } while (0)
+#endif
+
+#ifdef NDEBUG
+#define ASSERT_DEBUG_DEATH(fn, msg)
+#else
+#define ASSERT_DEBUG_DEATH(fn, msg) ASSERT_DEATH(fn, msg)
+#endif  // NDEBUG
+
+// Benchmark tools.
+
+#define BENCHMARK(n) static BenchmarkRegisterer __benchmark_ ## n (#n, &n);
+
+map<string, void (*)(int)> g_benchlist;  // the benchmarks to run
+
+class BenchmarkRegisterer {
+ public:
+  BenchmarkRegisterer(const char* name, void (*function)(int iters)) {
+    EXPECT_TRUE(g_benchlist.insert(std::make_pair(name, function)).second);
+  }
+};
+
+static inline void RunSpecifiedBenchmarks() {
+  if (!FLAGS_run_benchmark) {
+    return;
+  }
+
+  int iter_cnt = FLAGS_benchmark_iters;
+  puts("Benchmark\tTime(ns)\tIterations");
+  for (map<string, void (*)(int)>::const_iterator iter = g_benchlist.begin();
+       iter != g_benchlist.end();
+       ++iter) {
+    clock_t start = clock();
+    iter->second(iter_cnt);
+    double elapsed_ns =
+        ((double)clock() - start) / CLOCKS_PER_SEC * 1000*1000*1000;
+    printf("%s\t%8.2lf\t%10d\n",
+           iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt);
+  }
+  puts("");
+}
+
+// ----------------------------------------------------------------------
+// Golden file functions
+// ----------------------------------------------------------------------
+
+class CapturedStream {
+ public:
+  CapturedStream(int fd, const string & filename) :
+    fd_(fd),
+    uncaptured_fd_(-1),
+    filename_(filename) {
+    Capture();
+  }
+
+  ~CapturedStream() {
+    if (uncaptured_fd_ != -1) {
+      CHECK(close(uncaptured_fd_) != -1);
+    }
+  }
+
+  // Start redirecting output to a file
+  void Capture() {
+    // Keep original stream for later
+    CHECK(uncaptured_fd_ == -1) << ", Stream " << fd_ << " already captured!";
+    uncaptured_fd_ = dup(fd_);
+    CHECK(uncaptured_fd_ != -1);
+
+    // Open file to save stream to
+    int cap_fd = open(filename_.c_str(),
+                      O_CREAT | O_TRUNC | O_WRONLY,
+                      S_IRUSR | S_IWUSR);
+    CHECK(cap_fd != -1);
+
+    // Send stdout/stderr to this file
+    fflush(NULL);
+    CHECK(dup2(cap_fd, fd_) != -1);
+    CHECK(close(cap_fd) != -1);
+  }
+
+  // Remove output redirection
+  void StopCapture() {
+    // Restore original stream
+    if (uncaptured_fd_ != -1) {
+      fflush(NULL);
+      CHECK(dup2(uncaptured_fd_, fd_) != -1);
+    }
+  }
+
+  const string & filename() const { return filename_; }
+
+ private:
+  int fd_;             // file descriptor being captured
+  int uncaptured_fd_;  // where the stream was originally being sent to
+  string filename_;    // file where stream is being saved
+};
+static CapturedStream * s_captured_streams[STDERR_FILENO+1];
+// Redirect a file descriptor to a file.
+//   fd       - Should be STDOUT_FILENO or STDERR_FILENO
+//   filename - File where output should be stored
+static inline void CaptureTestOutput(int fd, const string & filename) {
+  CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
+  CHECK(s_captured_streams[fd] == NULL);
+  s_captured_streams[fd] = new CapturedStream(fd, filename);
+}
+static inline void CaptureTestStderr() {
+  CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err");
+}
+// Return the size (in bytes) of a file
+static inline size_t GetFileSize(FILE * file) {
+  fseek(file, 0, SEEK_END);
+  return static_cast<size_t>(ftell(file));
+}
+// Read the entire content of a file as a string
+static inline string ReadEntireFile(FILE * file) {
+  const size_t file_size = GetFileSize(file);
+  char * const buffer = new char[file_size];
+
+  size_t bytes_last_read = 0;  // # of bytes read in the last fread()
+  size_t bytes_read = 0;       // # of bytes read so far
+
+  fseek(file, 0, SEEK_SET);
+
+  // Keep reading the file until we cannot read further or the
+  // pre-determined file size is reached.
+  do {
+    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
+    bytes_read += bytes_last_read;
+  } while (bytes_last_read > 0 && bytes_read < file_size);
+
+  const string content = string(buffer, buffer+bytes_read);
+  delete[] buffer;
+
+  return content;
+}
+// Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when
+// fd is STDERR_FILENO) as a string
+static inline string GetCapturedTestOutput(int fd) {
+  CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO);
+  CapturedStream * const cap = s_captured_streams[fd];
+  CHECK(cap)
+    << ": did you forget CaptureTestStdout() or CaptureTestStderr()?";
+
+  // Make sure everything is flushed.
+  cap->StopCapture();
+
+  // Read the captured file.
+  FILE * const file = fopen(cap->filename().c_str(), "r");
+  const string content = ReadEntireFile(file);
+  fclose(file);
+
+  delete cap;
+  s_captured_streams[fd] = NULL;
+
+  return content;
+}
+// Get the captured stderr of a test as a string.
+static inline string GetCapturedTestStderr() {
+  return GetCapturedTestOutput(STDERR_FILENO);
+}
+
+// Check if the string is [IWEF](\d{4}|DATE)
+static inline bool IsLoggingPrefix(const string& s) {
+  if (s.size() != 5) return false;
+  if (!strchr("IWEF", s[0])) return false;
+  for (int i = 1; i <= 4; ++i) {
+    if (!isdigit(s[i]) && s[i] != "DATE"[i-1]) return false;
+  }
+  return true;
+}
+
+// Convert log output into normalized form.
+//
+// Example:
+//     I0102 030405 logging_unittest.cc:345] RAW: vlog -1
+//  => IDATE TIME__ logging_unittest.cc:LINE] RAW: vlog -1
+static inline string MungeLine(const string& line) {
+  std::istringstream iss(line);
+  string before, logcode_date, time, thread_lineinfo;
+  iss >> logcode_date;
+  while (!IsLoggingPrefix(logcode_date)) {
+    before += " " + logcode_date;
+    if (!(iss >> logcode_date)) {
+      // We cannot find the header of log output.
+      return before;
+    }
+  }
+  if (!before.empty()) before += " ";
+  iss >> time;
+  iss >> thread_lineinfo;
+  CHECK(!thread_lineinfo.empty());
+  if (thread_lineinfo[thread_lineinfo.size() - 1] != ']') {
+    // We found thread ID.
+    string tmp;
+    iss >> tmp;
+    CHECK(!tmp.empty());
+    CHECK_EQ(']', tmp[tmp.size() - 1]);
+    thread_lineinfo = "THREADID " + tmp;
+  }
+  size_t index = thread_lineinfo.find(':');
+  CHECK_NE(string::npos, index);
+  thread_lineinfo = thread_lineinfo.substr(0, index+1) + "LINE]";
+  string rest;
+  std::getline(iss, rest);
+  return (before + logcode_date[0] + "DATE TIME__ " + thread_lineinfo +
+          MungeLine(rest));
+}
+
+static inline void StringReplace(string* str,
+                          const string& oldsub,
+                          const string& newsub) {
+  size_t pos = str->find(oldsub);
+  if (pos != string::npos) {
+    str->replace(pos, oldsub.size(), newsub.c_str());
+  }
+}
+
+static inline string Munge(const string& filename) {
+  FILE* fp = fopen(filename.c_str(), "rb");
+  CHECK(fp != NULL) << filename << ": couldn't open";
+  char buf[4096];
+  string result;
+  while (fgets(buf, 4095, fp)) {
+    string line = MungeLine(buf);
+    char null_str[256];
+    char ptr_str[256];
+    sprintf(null_str, "%p", static_cast<void*>(NULL));
+    sprintf(ptr_str, "%p", reinterpret_cast<void*>(PTR_TEST_VALUE));
+
+    StringReplace(&line, "__NULLP__", null_str);
+    StringReplace(&line, "__PTRTEST__", ptr_str);
+
+    StringReplace(&line, "__SUCCESS__", StrError(0));
+    StringReplace(&line, "__ENOENT__", StrError(ENOENT));
+    StringReplace(&line, "__EINTR__", StrError(EINTR));
+    StringReplace(&line, "__ENXIO__", StrError(ENXIO));
+    StringReplace(&line, "__ENOEXEC__", StrError(ENOEXEC));
+    result += line + "\n";
+  }
+  fclose(fp);
+  return result;
+}
+
+static inline void WriteToFile(const string& body, const string& file) {
+  FILE* fp = fopen(file.c_str(), "wb");
+  fwrite(body.data(), 1, body.size(), fp);
+  fclose(fp);
+}
+
+static inline bool MungeAndDiffTestStderr(const string& golden_filename) {
+  CapturedStream* cap = s_captured_streams[STDERR_FILENO];
+  CHECK(cap) << ": did you forget CaptureTestStderr()?";
+
+  cap->StopCapture();
+
+  // Run munge
+  const string captured = Munge(cap->filename());
+  const string golden = Munge(golden_filename);
+  if (captured != golden) {
+    fprintf(stderr,
+            "Test with golden file failed. We'll try to show the diff:\n");
+    string munged_golden = golden_filename + ".munged";
+    WriteToFile(golden, munged_golden);
+    string munged_captured = cap->filename() + ".munged";
+    WriteToFile(captured, munged_captured);
+#ifdef OS_WINDOWS
+    string diffcmd("fc " + munged_golden + " " + munged_captured);
+#else
+    string diffcmd("diff -u " + munged_golden + " " + munged_captured);
+#endif
+    if (system(diffcmd.c_str()) != 0) {
+      fprintf(stderr, "diff command was failed.\n");
+    }
+    unlink(munged_golden.c_str());
+    unlink(munged_captured.c_str());
+    return false;
+  }
+  LOG(INFO) << "Diff was successful";
+  return true;
+}
+
+// Save flags used from logging_unittest.cc.
+#ifndef HAVE_LIB_GFLAGS
+struct FlagSaver {
+  FlagSaver()
+      : v_(FLAGS_v),
+        stderrthreshold_(FLAGS_stderrthreshold),
+        logtostderr_(FLAGS_logtostderr),
+        alsologtostderr_(FLAGS_alsologtostderr) {}
+  ~FlagSaver() {
+    FLAGS_v = v_;
+    FLAGS_stderrthreshold = stderrthreshold_;
+    FLAGS_logtostderr = logtostderr_;
+    FLAGS_alsologtostderr = alsologtostderr_;
+  }
+  int v_;
+  int stderrthreshold_;
+  bool logtostderr_;
+  bool alsologtostderr_;
+};
+#endif
+
+class Thread {
+ public:
+  virtual ~Thread() {}
+
+  void SetJoinable(bool) {}
+#if defined(OS_WINDOWS) && !defined(OS_CYGWIN)
+  void Start() {
+    handle_ = CreateThread(NULL,
+                           0,
+                           (LPTHREAD_START_ROUTINE)&Thread::InvokeThread,
+                           (LPVOID)this,
+                           0,
+                           &th_);
+    CHECK(handle_) << "CreateThread";
+  }
+  void Join() {
+    WaitForSingleObject(handle_, INFINITE);
+  }
+#elif defined(HAVE_PTHREAD)
+  void Start() {
+    pthread_create(&th_, NULL, &Thread::InvokeThread, this);
+  }
+  void Join() {
+    pthread_join(th_, NULL);
+  }
+#else
+# error No thread implementation.
+#endif
+
+ protected:
+  virtual void Run() = 0;
+
+ private:
+  static void* InvokeThread(void* self) {
+    ((Thread*)self)->Run();
+    return NULL;
+  }
+
+#if defined(OS_WINDOWS) && !defined(OS_CYGWIN)
+  HANDLE handle_;
+  DWORD th_;
+#else
+  pthread_t th_;
+#endif
+};
+
+static inline void SleepForMilliseconds(int t) {
+#ifndef OS_WINDOWS
+  usleep(t * 1000);
+#else
+  Sleep(t);
+#endif
+}
+
+// Add hook for operator new to ensure there are no memory allocation.
+
+void (*g_new_hook)() = NULL;
+
+_END_GOOGLE_NAMESPACE_
+
+void* operator new(size_t size) {
+  if (GOOGLE_NAMESPACE::g_new_hook) {
+    GOOGLE_NAMESPACE::g_new_hook();
+  }
+  return malloc(size);
+}
+
+void* operator new[](size_t size) {
+  return ::operator new(size);
+}
+
+void operator delete(void* p) {
+  free(p);
+}
+
+void operator delete[](void* p) {
+  ::operator delete(p);
+}
diff --git a/third_party/google-glog/src/logging.cc b/third_party/google-glog/src/logging.cc
new file mode 100644
index 0000000..ad4047d
--- /dev/null
+++ b/third_party/google-glog/src/logging.cc
@@ -0,0 +1,2181 @@
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite()
+
+#include "utilities.h"
+
+#include <algorithm>
+#include <assert.h>
+#include <iomanip>
+#include <string>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>  // For _exit.
+#endif
+#include <climits>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYS_UTSNAME_H
+# include <sys/utsname.h>  // For uname.
+#endif
+#include <fcntl.h>
+#include <cstdio>
+#include <iostream>
+#include <stdarg.h>
+#include <stdlib.h>
+#ifdef HAVE_PWD_H
+# include <pwd.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+# include <syslog.h>
+#endif
+#include <vector>
+#include <errno.h>                   // for errno
+#include <sstream>
+#include "base/commandlineflags.h"        // to get the program name
+#include "glog/logging.h"
+#include "glog/raw_logging.h"
+#include "base/googleinit.h"
+
+#ifdef HAVE_STACKTRACE
+# include "stacktrace.h"
+#endif
+
+using std::string;
+using std::vector;
+using std::setw;
+using std::setfill;
+using std::hex;
+using std::dec;
+using std::min;
+using std::ostream;
+using std::ostringstream;
+
+using std::FILE;
+using std::fwrite;
+using std::fclose;
+using std::fflush;
+using std::fprintf;
+using std::perror;
+
+#ifdef __QNX__
+using std::fdopen;
+#endif
+
+#ifdef _WIN32
+#define fdopen _fdopen
+#endif
+
+// There is no thread annotation support.
+#define EXCLUSIVE_LOCKS_REQUIRED(mu)
+
+static bool BoolFromEnv(const char *varname, bool defval) {
+  const char* const valstr = getenv(varname);
+  if (!valstr) {
+    return defval;
+  }
+  return memchr("tTyY1\0", valstr[0], 6) != NULL;
+}
+
+GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false),
+                 "log messages go to stderr instead of logfiles");
+GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false),
+                 "log messages go to stderr in addition to logfiles");
+GLOG_DEFINE_bool(colorlogtostderr, false,
+                 "color messages logged to stderr (if supported by terminal)");
+#ifdef OS_LINUX
+GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. "
+                 "Logs can grow very quickly and they are rarely read before they "
+                 "need to be evicted from memory. Instead, drop them from memory "
+                 "as soon as they are flushed to disk.");
+#endif
+
+// By default, errors (including fatal errors) get logged to stderr as
+// well as the file.
+//
+// The default is ERROR instead of FATAL so that users can see problems
+// when they run a program without having to look in another file.
+DEFINE_int32(stderrthreshold,
+             GOOGLE_NAMESPACE::GLOG_ERROR,
+             "log messages at or above this level are copied to stderr in "
+             "addition to logfiles.  This flag obsoletes --alsologtostderr.");
+
+GLOG_DEFINE_string(alsologtoemail, "",
+                   "log messages go to these email addresses "
+                   "in addition to logfiles");
+GLOG_DEFINE_bool(log_prefix, true,
+                 "Prepend the log prefix to the start of each log line");
+GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't "
+                  "actually get logged anywhere");
+GLOG_DEFINE_int32(logbuflevel, 0,
+                  "Buffer log messages logged at this level or lower"
+                  " (-1 means don't buffer; 0 means buffer INFO only;"
+                  " ...)");
+GLOG_DEFINE_int32(logbufsecs, 30,
+                  "Buffer log messages for at most this many seconds");
+GLOG_DEFINE_int32(logemaillevel, 999,
+                  "Email log messages logged at this level or higher"
+                  " (0 means email all; 3 means email FATAL only;"
+                  " ...)");
+GLOG_DEFINE_string(logmailer, "/bin/mail",
+                   "Mailer used to send logging email");
+
+// Compute the default value for --log_dir
+static const char* DefaultLogDir() {
+  const char* env;
+  env = getenv("GOOGLE_LOG_DIR");
+  if (env != NULL && env[0] != '\0') {
+    return env;
+  }
+  env = getenv("TEST_TMPDIR");
+  if (env != NULL && env[0] != '\0') {
+    return env;
+  }
+  return "";
+}
+
+GLOG_DEFINE_int32(logfile_mode, 0664, "Log file mode/permissions.");
+
+GLOG_DEFINE_string(log_dir, DefaultLogDir(),
+                   "If specified, logfiles are written into this directory instead "
+                   "of the default logging directory.");
+GLOG_DEFINE_string(log_link, "", "Put additional links to the log "
+                   "files in this directory");
+
+GLOG_DEFINE_int32(max_log_size, 1800,
+                  "approx. maximum log file size (in MB). A value of 0 will "
+                  "be silently overridden to 1.");
+
+GLOG_DEFINE_bool(stop_logging_if_full_disk, false,
+                 "Stop attempting to log to disk if the disk is full.");
+
+GLOG_DEFINE_string(log_backtrace_at, "",
+                   "Emit a backtrace when logging at file:linenum.");
+
+// TODO(hamaji): consider windows
+#define PATH_SEPARATOR '/'
+
+#ifndef HAVE_PREAD
+#if defined(OS_WINDOWS)
+#include <basetsd.h>
+#define ssize_t SSIZE_T
+#endif
+static ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
+  off_t orig_offset = lseek(fd, 0, SEEK_CUR);
+  if (orig_offset == (off_t)-1)
+    return -1;
+  if (lseek(fd, offset, SEEK_CUR) == (off_t)-1)
+    return -1;
+  ssize_t len = read(fd, buf, count);
+  if (len < 0)
+    return len;
+  if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1)
+    return -1;
+  return len;
+}
+#endif  // !HAVE_PREAD
+
+#ifndef HAVE_PWRITE
+static ssize_t pwrite(int fd, void* buf, size_t count, off_t offset) {
+  off_t orig_offset = lseek(fd, 0, SEEK_CUR);
+  if (orig_offset == (off_t)-1)
+    return -1;
+  if (lseek(fd, offset, SEEK_CUR) == (off_t)-1)
+    return -1;
+  ssize_t len = write(fd, buf, count);
+  if (len < 0)
+    return len;
+  if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1)
+    return -1;
+  return len;
+}
+#endif  // !HAVE_PWRITE
+
+static void GetHostName(string* hostname) {
+#if defined(HAVE_SYS_UTSNAME_H)
+  struct utsname buf;
+  if (0 != uname(&buf)) {
+    // ensure null termination on failure
+    *buf.nodename = '\0';
+  }
+  *hostname = buf.nodename;
+#elif defined(OS_WINDOWS)
+  char buf[MAX_COMPUTERNAME_LENGTH + 1];
+  DWORD len = MAX_COMPUTERNAME_LENGTH + 1;
+  if (GetComputerNameA(buf, &len)) {
+    *hostname = buf;
+  } else {
+    hostname->clear();
+  }
+#else
+# warning There is no way to retrieve the host name.
+  *hostname = "(unknown)";
+#endif
+}
+
+// Returns true iff terminal supports using colors in output.
+static bool TerminalSupportsColor() {
+  bool term_supports_color = false;
+#ifdef OS_WINDOWS
+  // on Windows TERM variable is usually not set, but the console does
+  // support colors.
+  term_supports_color = true;
+#else
+  // On non-Windows platforms, we rely on the TERM variable.
+  const char* const term = getenv("TERM");
+  if (term != NULL && term[0] != '\0') {
+    term_supports_color =
+      !strcmp(term, "xterm") ||
+      !strcmp(term, "xterm-color") ||
+      !strcmp(term, "xterm-256color") ||
+      !strcmp(term, "screen-256color") ||
+      !strcmp(term, "konsole") ||
+      !strcmp(term, "konsole-16color") ||
+      !strcmp(term, "konsole-256color") ||
+      !strcmp(term, "screen") ||
+      !strcmp(term, "linux") ||
+      !strcmp(term, "cygwin");
+  }
+#endif
+  return term_supports_color;
+}
+
+_START_GOOGLE_NAMESPACE_
+
+enum GLogColor {
+  COLOR_DEFAULT,
+  COLOR_RED,
+  COLOR_GREEN,
+  COLOR_YELLOW
+};
+
+static GLogColor SeverityToColor(LogSeverity severity) {
+  assert(severity >= 0 && severity < NUM_SEVERITIES);
+  GLogColor color = COLOR_DEFAULT;
+  switch (severity) {
+  case GLOG_INFO:
+    color = COLOR_DEFAULT;
+    break;
+  case GLOG_WARNING:
+    color = COLOR_YELLOW;
+    break;
+  case GLOG_ERROR:
+  case GLOG_FATAL:
+    color = COLOR_RED;
+    break;
+  default:
+    // should never get here.
+    assert(false);
+  }
+  return color;
+}
+
+#ifdef OS_WINDOWS
+
+// Returns the character attribute for the given color.
+static WORD GetColorAttribute(GLogColor color) {
+  switch (color) {
+    case COLOR_RED:    return FOREGROUND_RED;
+    case COLOR_GREEN:  return FOREGROUND_GREEN;
+    case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
+    default:           return 0;
+  }
+}
+
+#else
+
+// Returns the ANSI color code for the given color.
+static const char* GetAnsiColorCode(GLogColor color) {
+  switch (color) {
+  case COLOR_RED:     return "1";
+  case COLOR_GREEN:   return "2";
+  case COLOR_YELLOW:  return "3";
+  case COLOR_DEFAULT:  return "";
+  };
+  return NULL; // stop warning about return type.
+}
+
+#endif  // OS_WINDOWS
+
+// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0
+static int32 MaxLogSize() {
+  return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1);
+}
+
+// An arbitrary limit on the length of a single log message.  This
+// is so that streaming can be done more efficiently.
+const size_t LogMessage::kMaxLogMessageLen = 30000;
+
+struct LogMessage::LogMessageData  {
+  LogMessageData();
+
+  int preserved_errno_;      // preserved errno
+  // Buffer space; contains complete message text.
+  char message_text_[LogMessage::kMaxLogMessageLen+1];
+  LogStream stream_;
+  char severity_;      // What level is this LogMessage logged at?
+  int line_;                 // line number where logging call is.
+  void (LogMessage::*send_method_)();  // Call this in destructor to send
+  union {  // At most one of these is used: union to keep the size low.
+    LogSink* sink_;             // NULL or sink to send message to
+    std::vector<std::string>* outvec_; // NULL or vector to push message onto
+    std::string* message_;             // NULL or string to write message into
+  };
+  time_t timestamp_;            // Time of creation of LogMessage
+  struct ::tm tm_time_;         // Time of creation of LogMessage
+  size_t num_prefix_chars_;     // # of chars of prefix in this message
+  size_t num_chars_to_log_;     // # of chars of msg to send to log
+  size_t num_chars_to_syslog_;  // # of chars of msg to send to syslog
+  const char* basename_;        // basename of file that called LOG
+  const char* fullname_;        // fullname of file that called LOG
+  bool has_been_flushed_;       // false => data has not been flushed
+  bool first_fatal_;            // true => this was first fatal msg
+
+ private:
+  LogMessageData(const LogMessageData&);
+  void operator=(const LogMessageData&);
+};
+
+// A mutex that allows only one thread to log at a time, to keep things from
+// getting jumbled.  Some other very uncommon logging operations (like
+// changing the destination file for log messages of a given severity) also
+// lock this mutex.  Please be sure that anybody who might possibly need to
+// lock it does so.
+static Mutex log_mutex;
+
+// Number of messages sent at each severity.  Under log_mutex.
+int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0};
+
+// Globally disable log writing (if disk is full)
+static bool stop_writing = false;
+
+const char*const LogSeverityNames[NUM_SEVERITIES] = {
+  "INFO", "WARNING", "ERROR", "FATAL"
+};
+
+// Has the user called SetExitOnDFatal(true)?
+static bool exit_on_dfatal = true;
+
+const char* GetLogSeverityName(LogSeverity severity) {
+  return LogSeverityNames[severity];
+}
+
+static bool SendEmailInternal(const char*dest, const char *subject,
+                              const char*body, bool use_logging);
+
+base::Logger::~Logger() {
+}
+
+namespace {
+
+// Encapsulates all file-system related state
+class LogFileObject : public base::Logger {
+ public:
+  LogFileObject(LogSeverity severity, const char* base_filename);
+  ~LogFileObject();
+
+  virtual void Write(bool force_flush, // Should we force a flush here?
+                     time_t timestamp,  // Timestamp for this entry
+                     const char* message,
+                     int message_len);
+
+  // Configuration options
+  void SetBasename(const char* basename);
+  void SetExtension(const char* ext);
+  void SetSymlinkBasename(const char* symlink_basename);
+
+  // Normal flushing routine
+  virtual void Flush();
+
+  // It is the actual file length for the system loggers,
+  // i.e., INFO, ERROR, etc.
+  virtual uint32 LogSize() {
+    MutexLock l(&lock_);
+    return file_length_;
+  }
+
+  // Internal flush routine.  Exposed so that FlushLogFilesUnsafe()
+  // can avoid grabbing a lock.  Usually Flush() calls it after
+  // acquiring lock_.
+  void FlushUnlocked();
+
+ private:
+  static const uint32 kRolloverAttemptFrequency = 0x20;
+
+  Mutex lock_;
+  bool base_filename_selected_;
+  string base_filename_;
+  string symlink_basename_;
+  string filename_extension_;     // option users can specify (eg to add port#)
+  FILE* file_;
+  LogSeverity severity_;
+  uint32 bytes_since_flush_;
+  uint32 dropped_mem_length_;
+  uint32 file_length_;
+  unsigned int rollover_attempt_;
+  int64 next_flush_time_;         // cycle count at which to flush log
+
+  // Actually create a logfile using the value of base_filename_ and the
+  // supplied argument time_pid_string
+  // REQUIRES: lock_ is held
+  bool CreateLogfile(const string& time_pid_string);
+};
+
+}  // namespace
+
+class LogDestination {
+ public:
+  friend class LogMessage;
+  friend void ReprintFatalMessage();
+  friend base::Logger* base::GetLogger(LogSeverity);
+  friend void base::SetLogger(LogSeverity, base::Logger*);
+
+  // These methods are just forwarded to by their global versions.
+  static void SetLogDestination(LogSeverity severity,
+				const char* base_filename);
+  static void SetLogSymlink(LogSeverity severity,
+                            const char* symlink_basename);
+  static void AddLogSink(LogSink *destination);
+  static void RemoveLogSink(LogSink *destination);
+  static void SetLogFilenameExtension(const char* filename_extension);
+  static void SetStderrLogging(LogSeverity min_severity);
+  static void SetEmailLogging(LogSeverity min_severity, const char* addresses);
+  static void LogToStderr();
+  // Flush all log files that are at least at the given severity level
+  static void FlushLogFiles(int min_severity);
+  static void FlushLogFilesUnsafe(int min_severity);
+
+  // we set the maximum size of our packet to be 1400, the logic being
+  // to prevent fragmentation.
+  // Really this number is arbitrary.
+  static const int kNetworkBytes = 1400;
+
+  static const string& hostname();
+  static const bool& terminal_supports_color() {
+    return terminal_supports_color_;
+  }
+
+  static void DeleteLogDestinations();
+
+ private:
+  LogDestination(LogSeverity severity, const char* base_filename);
+  ~LogDestination() { }
+
+  // Take a log message of a particular severity and log it to stderr
+  // iff it's of a high enough severity to deserve it.
+  static void MaybeLogToStderr(LogSeverity severity, const char* message,
+			       size_t len);
+
+  // Take a log message of a particular severity and log it to email
+  // iff it's of a high enough severity to deserve it.
+  static void MaybeLogToEmail(LogSeverity severity, const char* message,
+			      size_t len);
+  // Take a log message of a particular severity and log it to a file
+  // iff the base filename is not "" (which means "don't log to me")
+  static void MaybeLogToLogfile(LogSeverity severity,
+                                time_t timestamp,
+				const char* message, size_t len);
+  // Take a log message of a particular severity and log it to the file
+  // for that severity and also for all files with severity less than
+  // this severity.
+  static void LogToAllLogfiles(LogSeverity severity,
+                               time_t timestamp,
+                               const char* message, size_t len);
+
+  // Send logging info to all registered sinks.
+  static void LogToSinks(LogSeverity severity,
+                         const char *full_filename,
+                         const char *base_filename,
+                         int line,
+                         const struct ::tm* tm_time,
+                         const char* message,
+                         size_t message_len);
+
+  // Wait for all registered sinks via WaitTillSent
+  // including the optional one in "data".
+  static void WaitForSinks(LogMessage::LogMessageData* data);
+
+  static LogDestination* log_destination(LogSeverity severity);
+
+  LogFileObject fileobject_;
+  base::Logger* logger_;      // Either &fileobject_, or wrapper around it
+
+  static LogDestination* log_destinations_[NUM_SEVERITIES];
+  static LogSeverity email_logging_severity_;
+  static string addresses_;
+  static string hostname_;
+  static bool terminal_supports_color_;
+
+  // arbitrary global logging destinations.
+  static vector<LogSink*>* sinks_;
+
+  // Protects the vector sinks_,
+  // but not the LogSink objects its elements reference.
+  static Mutex sink_mutex_;
+
+  // Disallow
+  LogDestination(const LogDestination&);
+  LogDestination& operator=(const LogDestination&);
+};
+
+// Errors do not get logged to email by default.
+LogSeverity LogDestination::email_logging_severity_ = 99999;
+
+string LogDestination::addresses_;
+string LogDestination::hostname_;
+
+vector<LogSink*>* LogDestination::sinks_ = NULL;
+Mutex LogDestination::sink_mutex_;
+bool LogDestination::terminal_supports_color_ = TerminalSupportsColor();
+
+/* static */
+const string& LogDestination::hostname() {
+  if (hostname_.empty()) {
+    GetHostName(&hostname_);
+    if (hostname_.empty()) {
+      hostname_ = "(unknown)";
+    }
+  }
+  return hostname_;
+}
+
+LogDestination::LogDestination(LogSeverity severity,
+                               const char* base_filename)
+  : fileobject_(severity, base_filename),
+    logger_(&fileobject_) {
+}
+
+inline void LogDestination::FlushLogFilesUnsafe(int min_severity) {
+  // assume we have the log_mutex or we simply don't care
+  // about it
+  for (int i = min_severity; i < NUM_SEVERITIES; i++) {
+    LogDestination* log = log_destinations_[i];
+    if (log != NULL) {
+      // Flush the base fileobject_ logger directly instead of going
+      // through any wrappers to reduce chance of deadlock.
+      log->fileobject_.FlushUnlocked();
+    }
+  }
+}
+
+inline void LogDestination::FlushLogFiles(int min_severity) {
+  // Prevent any subtle race conditions by wrapping a mutex lock around
+  // all this stuff.
+  MutexLock l(&log_mutex);
+  for (int i = min_severity; i < NUM_SEVERITIES; i++) {
+    LogDestination* log = log_destination(i);
+    if (log != NULL) {
+      log->logger_->Flush();
+    }
+  }
+}
+
+inline void LogDestination::SetLogDestination(LogSeverity severity,
+					      const char* base_filename) {
+  assert(severity >= 0 && severity < NUM_SEVERITIES);
+  // Prevent any subtle race conditions by wrapping a mutex lock around
+  // all this stuff.
+  MutexLock l(&log_mutex);
+  log_destination(severity)->fileobject_.SetBasename(base_filename);
+}
+
+inline void LogDestination::SetLogSymlink(LogSeverity severity,
+                                          const char* symlink_basename) {
+  CHECK_GE(severity, 0);
+  CHECK_LT(severity, NUM_SEVERITIES);
+  MutexLock l(&log_mutex);
+  log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename);
+}
+
+inline void LogDestination::AddLogSink(LogSink *destination) {
+  // Prevent any subtle race conditions by wrapping a mutex lock around
+  // all this stuff.
+  MutexLock l(&sink_mutex_);
+  if (!sinks_)  sinks_ = new vector<LogSink*>;
+  sinks_->push_back(destination);
+}
+
+inline void LogDestination::RemoveLogSink(LogSink *destination) {
+  // Prevent any subtle race conditions by wrapping a mutex lock around
+  // all this stuff.
+  MutexLock l(&sink_mutex_);
+  // This doesn't keep the sinks in order, but who cares?
+  if (sinks_) {
+    for (int i = sinks_->size() - 1; i >= 0; i--) {
+      if ((*sinks_)[i] == destination) {
+        (*sinks_)[i] = (*sinks_)[sinks_->size() - 1];
+        sinks_->pop_back();
+        break;
+      }
+    }
+  }
+}
+
+inline void LogDestination::SetLogFilenameExtension(const char* ext) {
+  // Prevent any subtle race conditions by wrapping a mutex lock around
+  // all this stuff.
+  MutexLock l(&log_mutex);
+  for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) {
+    log_destination(severity)->fileobject_.SetExtension(ext);
+  }
+}
+
+inline void LogDestination::SetStderrLogging(LogSeverity min_severity) {
+  assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
+  // Prevent any subtle race conditions by wrapping a mutex lock around
+  // all this stuff.
+  MutexLock l(&log_mutex);
+  FLAGS_stderrthreshold = min_severity;
+}
+
+inline void LogDestination::LogToStderr() {
+  // *Don't* put this stuff in a mutex lock, since SetStderrLogging &
+  // SetLogDestination already do the locking!
+  SetStderrLogging(0);            // thus everything is "also" logged to stderr
+  for ( int i = 0; i < NUM_SEVERITIES; ++i ) {
+    SetLogDestination(i, "");     // "" turns off logging to a logfile
+  }
+}
+
+inline void LogDestination::SetEmailLogging(LogSeverity min_severity,
+					    const char* addresses) {
+  assert(min_severity >= 0 && min_severity < NUM_SEVERITIES);
+  // Prevent any subtle race conditions by wrapping a mutex lock around
+  // all this stuff.
+  MutexLock l(&log_mutex);
+  LogDestination::email_logging_severity_ = min_severity;
+  LogDestination::addresses_ = addresses;
+}
+
+static void ColoredWriteToStderr(LogSeverity severity,
+                                 const char* message, size_t len) {
+  const GLogColor color =
+      (LogDestination::terminal_supports_color() && FLAGS_colorlogtostderr) ?
+      SeverityToColor(severity) : COLOR_DEFAULT;
+
+  // Avoid using cerr from this module since we may get called during
+  // exit code, and cerr may be partially or fully destroyed by then.
+  if (COLOR_DEFAULT == color) {
+    fwrite(message, len, 1, stderr);
+    return;
+  }
+#ifdef OS_WINDOWS
+  const HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
+
+  // Gets the current text color.
+  CONSOLE_SCREEN_BUFFER_INFO buffer_info;
+  GetConsoleScreenBufferInfo(stderr_handle, &buffer_info);
+  const WORD old_color_attrs = buffer_info.wAttributes;
+
+  // We need to flush the stream buffers into the console before each
+  // SetConsoleTextAttribute call lest it affect the text that is already
+  // printed but has not yet reached the console.
+  fflush(stderr);
+  SetConsoleTextAttribute(stderr_handle,
+                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
+  fwrite(message, len, 1, stderr);
+  fflush(stderr);
+  // Restores the text color.
+  SetConsoleTextAttribute(stderr_handle, old_color_attrs);
+#else
+  fprintf(stderr, "\033[0;3%sm", GetAnsiColorCode(color));
+  fwrite(message, len, 1, stderr);
+  fprintf(stderr, "\033[m");  // Resets the terminal to default.
+#endif  // OS_WINDOWS
+}
+
+static void WriteToStderr(const char* message, size_t len) {
+  // Avoid using cerr from this module since we may get called during
+  // exit code, and cerr may be partially or fully destroyed by then.
+  fwrite(message, len, 1, stderr);
+}
+
+inline void LogDestination::MaybeLogToStderr(LogSeverity severity,
+					     const char* message, size_t len) {
+  if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) {
+    ColoredWriteToStderr(severity, message, len);
+#ifdef OS_WINDOWS
+    // On Windows, also output to the debugger
+    ::OutputDebugStringA(string(message,len).c_str());
+#endif
+  }
+}
+
+
+inline void LogDestination::MaybeLogToEmail(LogSeverity severity,
+					    const char* message, size_t len) {
+  if (severity >= email_logging_severity_ ||
+      severity >= FLAGS_logemaillevel) {
+    string to(FLAGS_alsologtoemail);
+    if (!addresses_.empty()) {
+      if (!to.empty()) {
+        to += ",";
+      }
+      to += addresses_;
+    }
+    const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " +
+                         glog_internal_namespace_::ProgramInvocationShortName());
+    string body(hostname());
+    body += "\n\n";
+    body.append(message, len);
+
+    // should NOT use SendEmail().  The caller of this function holds the
+    // log_mutex and SendEmail() calls LOG/VLOG which will block trying to
+    // acquire the log_mutex object.  Use SendEmailInternal() and set
+    // use_logging to false.
+    SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false);
+  }
+}
+
+
+inline void LogDestination::MaybeLogToLogfile(LogSeverity severity,
+                                              time_t timestamp,
+					      const char* message,
+					      size_t len) {
+  const bool should_flush = severity > FLAGS_logbuflevel;
+  LogDestination* destination = log_destination(severity);
+  destination->logger_->Write(should_flush, timestamp, message, len);
+}
+
+inline void LogDestination::LogToAllLogfiles(LogSeverity severity,
+                                             time_t timestamp,
+                                             const char* message,
+                                             size_t len) {
+
+  if ( FLAGS_logtostderr ) {           // global flag: never log to file
+    ColoredWriteToStderr(severity, message, len);
+  } else {
+    for (int i = severity; i >= 0; --i)
+      LogDestination::MaybeLogToLogfile(i, timestamp, message, len);
+  }
+}
+
+inline void LogDestination::LogToSinks(LogSeverity severity,
+                                       const char *full_filename,
+                                       const char *base_filename,
+                                       int line,
+                                       const struct ::tm* tm_time,
+                                       const char* message,
+                                       size_t message_len) {
+  ReaderMutexLock l(&sink_mutex_);
+  if (sinks_) {
+    for (int i = sinks_->size() - 1; i >= 0; i--) {
+      (*sinks_)[i]->send(severity, full_filename, base_filename,
+                         line, tm_time, message, message_len);
+    }
+  }
+}
+
+inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) {
+  ReaderMutexLock l(&sink_mutex_);
+  if (sinks_) {
+    for (int i = sinks_->size() - 1; i >= 0; i--) {
+      (*sinks_)[i]->WaitTillSent();
+    }
+  }
+  const bool send_to_sink =
+      (data->send_method_ == &LogMessage::SendToSink) ||
+      (data->send_method_ == &LogMessage::SendToSinkAndLog);
+  if (send_to_sink && data->sink_ != NULL) {
+    data->sink_->WaitTillSent();
+  }
+}
+
+LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES];
+
+inline LogDestination* LogDestination::log_destination(LogSeverity severity) {
+  assert(severity >=0 && severity < NUM_SEVERITIES);
+  if (!log_destinations_[severity]) {
+    log_destinations_[severity] = new LogDestination(severity, NULL);
+  }
+  return log_destinations_[severity];
+}
+
+void LogDestination::DeleteLogDestinations() {
+  for (int severity = 0; severity < NUM_SEVERITIES; ++severity) {
+    delete log_destinations_[severity];
+    log_destinations_[severity] = NULL;
+  }
+  MutexLock l(&sink_mutex_);
+  delete sinks_;
+  sinks_ = NULL;
+}
+
+namespace {
+
+LogFileObject::LogFileObject(LogSeverity severity,
+                             const char* base_filename)
+  : base_filename_selected_(base_filename != NULL),
+    base_filename_((base_filename != NULL) ? base_filename : ""),
+    symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()),
+    filename_extension_(),
+    file_(NULL),
+    severity_(severity),
+    bytes_since_flush_(0),
+    dropped_mem_length_(0),
+    file_length_(0),
+    rollover_attempt_(kRolloverAttemptFrequency-1),
+    next_flush_time_(0) {
+  assert(severity >= 0);
+  assert(severity < NUM_SEVERITIES);
+}
+
+LogFileObject::~LogFileObject() {
+  MutexLock l(&lock_);
+  if (file_ != NULL) {
+    fclose(file_);
+    file_ = NULL;
+  }
+}
+
+void LogFileObject::SetBasename(const char* basename) {
+  MutexLock l(&lock_);
+  base_filename_selected_ = true;
+  if (base_filename_ != basename) {
+    // Get rid of old log file since we are changing names
+    if (file_ != NULL) {
+      fclose(file_);
+      file_ = NULL;
+      rollover_attempt_ = kRolloverAttemptFrequency-1;
+    }
+    base_filename_ = basename;
+  }
+}
+
+void LogFileObject::SetExtension(const char* ext) {
+  MutexLock l(&lock_);
+  if (filename_extension_ != ext) {
+    // Get rid of old log file since we are changing names
+    if (file_ != NULL) {
+      fclose(file_);
+      file_ = NULL;
+      rollover_attempt_ = kRolloverAttemptFrequency-1;
+    }
+    filename_extension_ = ext;
+  }
+}
+
+void LogFileObject::SetSymlinkBasename(const char* symlink_basename) {
+  MutexLock l(&lock_);
+  symlink_basename_ = symlink_basename;
+}
+
+void LogFileObject::Flush() {
+  MutexLock l(&lock_);
+  FlushUnlocked();
+}
+
+void LogFileObject::FlushUnlocked(){
+  if (file_ != NULL) {
+    fflush(file_);
+    bytes_since_flush_ = 0;
+  }
+  // Figure out when we are due for another flush.
+  const int64 next = (FLAGS_logbufsecs
+                      * static_cast<int64>(1000000));  // in usec
+  next_flush_time_ = CycleClock_Now() + UsecToCycles(next);
+}
+
+bool LogFileObject::CreateLogfile(const string& time_pid_string) {
+  string string_filename = base_filename_+filename_extension_+
+                           time_pid_string;
+  const char* filename = string_filename.c_str();
+  int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, FLAGS_logfile_mode);
+  if (fd == -1) return false;
+#ifdef HAVE_FCNTL
+  // Mark the file close-on-exec. We don't really care if this fails
+  fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+  file_ = fdopen(fd, "a");  // Make a FILE*.
+  if (file_ == NULL) {  // Man, we're screwed!
+    close(fd);
+    unlink(filename);  // Erase the half-baked evidence: an unusable log file
+    return false;
+  }
+
+  // We try to create a symlink called <program_name>.<severity>,
+  // which is easier to use.  (Every time we create a new logfile,
+  // we destroy the old symlink and create a new one, so it always
+  // points to the latest logfile.)  If it fails, we're sad but it's
+  // no error.
+  if (!symlink_basename_.empty()) {
+    // take directory from filename
+    const char* slash = strrchr(filename, PATH_SEPARATOR);
+    const string linkname =
+      symlink_basename_ + '.' + LogSeverityNames[severity_];
+    string linkpath;
+    if ( slash ) linkpath = string(filename, slash-filename+1);  // get dirname
+    linkpath += linkname;
+    unlink(linkpath.c_str());                    // delete old one if it exists
+
+#if defined(OS_WINDOWS)
+    // TODO(hamaji): Create lnk file on Windows?
+#elif defined(HAVE_UNISTD_H)
+    // We must have unistd.h.
+    // Make the symlink be relative (in the same dir) so that if the
+    // entire log directory gets relocated the link is still valid.
+    const char *linkdest = slash ? (slash + 1) : filename;
+    if (symlink(linkdest, linkpath.c_str()) != 0) {
+      // silently ignore failures
+    }
+
+    // Make an additional link to the log file in a place specified by
+    // FLAGS_log_link, if indicated
+    if (!FLAGS_log_link.empty()) {
+      linkpath = FLAGS_log_link + "/" + linkname;
+      unlink(linkpath.c_str());                  // delete old one if it exists
+      if (symlink(filename, linkpath.c_str()) != 0) {
+        // silently ignore failures
+      }
+    }
+#endif
+  }
+
+  return true;  // Everything worked
+}
+
+void LogFileObject::Write(bool force_flush,
+                          time_t timestamp,
+                          const char* message,
+                          int message_len) {
+  MutexLock l(&lock_);
+
+  // We don't log if the base_name_ is "" (which means "don't write")
+  if (base_filename_selected_ && base_filename_.empty()) {
+    return;
+  }
+
+  if (static_cast<int>(file_length_ >> 20) >= MaxLogSize() ||
+      PidHasChanged()) {
+    if (file_ != NULL) fclose(file_);
+    file_ = NULL;
+    file_length_ = bytes_since_flush_ = dropped_mem_length_ = 0;
+    rollover_attempt_ = kRolloverAttemptFrequency-1;
+  }
+
+  // If there's no destination file, make one before outputting
+  if (file_ == NULL) {
+    // Try to rollover the log file every 32 log messages.  The only time
+    // this could matter would be when we have trouble creating the log
+    // file.  If that happens, we'll lose lots of log messages, of course!
+    if (++rollover_attempt_ != kRolloverAttemptFrequency) return;
+    rollover_attempt_ = 0;
+
+    struct ::tm tm_time;
+    localtime_r(&timestamp, &tm_time);
+
+    // The logfile's filename will have the date/time & pid in it
+    ostringstream time_pid_stream;
+    time_pid_stream.fill('0');
+    time_pid_stream << 1900+tm_time.tm_year
+                    << setw(2) << 1+tm_time.tm_mon
+                    << setw(2) << tm_time.tm_mday
+                    << '-'
+                    << setw(2) << tm_time.tm_hour
+                    << setw(2) << tm_time.tm_min
+                    << setw(2) << tm_time.tm_sec
+                    << '.'
+                    << GetMainThreadPid();
+    const string& time_pid_string = time_pid_stream.str();
+
+    if (base_filename_selected_) {
+      if (!CreateLogfile(time_pid_string)) {
+        perror("Could not create log file");
+        fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n",
+                time_pid_string.c_str());
+        return;
+      }
+    } else {
+      // If no base filename for logs of this severity has been set, use a
+      // default base filename of
+      // "<program name>.<hostname>.<user name>.log.<severity level>.".  So
+      // logfiles will have names like
+      // webserver.examplehost.root.log.INFO.19990817-150000.4354, where
+      // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00),
+      // and 4354 is the pid of the logging process.  The date & time reflect
+      // when the file was created for output.
+      //
+      // Where does the file get put?  Successively try the directories
+      // "/tmp", and "."
+      string stripped_filename(
+          glog_internal_namespace_::ProgramInvocationShortName());
+      string hostname;
+      GetHostName(&hostname);
+
+      string uidname = MyUserName();
+      // We should not call CHECK() here because this function can be
+      // called after holding on to log_mutex. We don't want to
+      // attempt to hold on to the same mutex, and get into a
+      // deadlock. Simply use a name like invalid-user.
+      if (uidname.empty()) uidname = "invalid-user";
+
+      stripped_filename = stripped_filename+'.'+hostname+'.'
+                          +uidname+".log."
+                          +LogSeverityNames[severity_]+'.';
+      // We're going to (potentially) try to put logs in several different dirs
+      const vector<string> & log_dirs = GetLoggingDirectories();
+
+      // Go through the list of dirs, and try to create the log file in each
+      // until we succeed or run out of options
+      bool success = false;
+      for (vector<string>::const_iterator dir = log_dirs.begin();
+           dir != log_dirs.end();
+           ++dir) {
+        base_filename_ = *dir + "/" + stripped_filename;
+        if ( CreateLogfile(time_pid_string) ) {
+          success = true;
+          break;
+        }
+      }
+      // If we never succeeded, we have to give up
+      if ( success == false ) {
+        perror("Could not create logging file");
+        fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!",
+                time_pid_string.c_str());
+        return;
+      }
+    }
+
+    // Write a header message into the log file
+    ostringstream file_header_stream;
+    file_header_stream.fill('0');
+    file_header_stream << "Log file created at: "
+                       << 1900+tm_time.tm_year << '/'
+                       << setw(2) << 1+tm_time.tm_mon << '/'
+                       << setw(2) << tm_time.tm_mday
+                       << ' '
+                       << setw(2) << tm_time.tm_hour << ':'
+                       << setw(2) << tm_time.tm_min << ':'
+                       << setw(2) << tm_time.tm_sec << '\n'
+                       << "Running on machine: "
+                       << LogDestination::hostname() << '\n'
+                       << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu "
+                       << "threadid file:line] msg" << '\n';
+    const string& file_header_string = file_header_stream.str();
+
+    const int header_len = file_header_string.size();
+    fwrite(file_header_string.data(), 1, header_len, file_);
+    file_length_ += header_len;
+    bytes_since_flush_ += header_len;
+  }
+
+  // Write to LOG file
+  if ( !stop_writing ) {
+    // fwrite() doesn't return an error when the disk is full, for
+    // messages that are less than 4096 bytes. When the disk is full,
+    // it returns the message length for messages that are less than
+    // 4096 bytes. fwrite() returns 4096 for message lengths that are
+    // greater than 4096, thereby indicating an error.
+    errno = 0;
+    fwrite(message, 1, message_len, file_);
+    if ( FLAGS_stop_logging_if_full_disk &&
+         errno == ENOSPC ) {  // disk full, stop writing to disk
+      stop_writing = true;  // until the disk is
+      return;
+    } else {
+      file_length_ += message_len;
+      bytes_since_flush_ += message_len;
+    }
+  } else {
+    if ( CycleClock_Now() >= next_flush_time_ )
+      stop_writing = false;  // check to see if disk has free space.
+    return;  // no need to flush
+  }
+
+  // See important msgs *now*.  Also, flush logs at least every 10^6 chars,
+  // or every "FLAGS_logbufsecs" seconds.
+  if ( force_flush ||
+       (bytes_since_flush_ >= 1000000) ||
+       (CycleClock_Now() >= next_flush_time_) ) {
+    FlushUnlocked();
+#ifdef OS_LINUX
+    // Only consider files >= 3MiB
+    if (FLAGS_drop_log_memory && file_length_ >= (3 << 20)) {
+      // Don't evict the most recent 1-2MiB so as not to impact a tailer
+      // of the log file and to avoid page rounding issue on linux < 4.7
+      uint32 total_drop_length = (file_length_ & ~((1 << 20) - 1)) - (1 << 20);
+      uint32 this_drop_length = total_drop_length - dropped_mem_length_;
+      if (this_drop_length >= (2 << 20)) {
+        // Only advise when >= 2MiB to drop
+        posix_fadvise(fileno(file_), dropped_mem_length_, this_drop_length,
+                      POSIX_FADV_DONTNEED);
+        dropped_mem_length_ = total_drop_length;
+      }
+    }
+#endif
+  }
+}
+
+}  // namespace
+
+
+// Static log data space to avoid alloc failures in a LOG(FATAL)
+//
+// Since multiple threads may call LOG(FATAL), and we want to preserve
+// the data from the first call, we allocate two sets of space.  One
+// for exclusive use by the first thread, and one for shared use by
+// all other threads.
+static Mutex fatal_msg_lock;
+static CrashReason crash_reason;
+static bool fatal_msg_exclusive = true;
+static LogMessage::LogMessageData fatal_msg_data_exclusive;
+static LogMessage::LogMessageData fatal_msg_data_shared;
+
+#ifdef GLOG_THREAD_LOCAL_STORAGE
+// Static thread-local log data space to use, because typically at most one
+// LogMessageData object exists (in this case glog makes zero heap memory
+// allocations).
+static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true;
+
+#ifdef HAVE_ALIGNED_STORAGE
+static GLOG_THREAD_LOCAL_STORAGE
+    std::aligned_storage<sizeof(LogMessage::LogMessageData),
+                         alignof(LogMessage::LogMessageData)>::type thread_msg_data;
+#else
+static GLOG_THREAD_LOCAL_STORAGE
+    char thread_msg_data[sizeof(void*) + sizeof(LogMessage::LogMessageData)];
+#endif  // HAVE_ALIGNED_STORAGE
+#endif  // defined(GLOG_THREAD_LOCAL_STORAGE)
+
+LogMessage::LogMessageData::LogMessageData()
+  : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+                       int ctr, void (LogMessage::*send_method)())
+    : allocated_(NULL) {
+  Init(file, line, severity, send_method);
+  data_->stream_.set_ctr(ctr);
+}
+
+LogMessage::LogMessage(const char* file, int line,
+                       const CheckOpString& result)
+    : allocated_(NULL) {
+  Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
+  stream() << "Check failed: " << (*result.str_) << " ";
+}
+
+LogMessage::LogMessage(const char* file, int line)
+    : allocated_(NULL) {
+  Init(file, line, GLOG_INFO, &LogMessage::SendToLog);
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
+    : allocated_(NULL) {
+  Init(file, line, severity, &LogMessage::SendToLog);
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+                       LogSink* sink, bool also_send_to_log)
+    : allocated_(NULL) {
+  Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog :
+                                                &LogMessage::SendToSink);
+  data_->sink_ = sink;  // override Init()'s setting to NULL
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+                       vector<string> *outvec)
+    : allocated_(NULL) {
+  Init(file, line, severity, &LogMessage::SaveOrSendToLog);
+  data_->outvec_ = outvec; // override Init()'s setting to NULL
+}
+
+LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
+                       string *message)
+    : allocated_(NULL) {
+  Init(file, line, severity, &LogMessage::WriteToStringAndLog);
+  data_->message_ = message;  // override Init()'s setting to NULL
+}
+
+void LogMessage::Init(const char* file,
+                      int line,
+                      LogSeverity severity,
+                      void (LogMessage::*send_method)()) {
+  allocated_ = NULL;
+  if (severity != GLOG_FATAL || !exit_on_dfatal) {
+#ifdef GLOG_THREAD_LOCAL_STORAGE
+    // No need for locking, because this is thread local.
+    if (thread_data_available) {
+      thread_data_available = false;
+#ifdef HAVE_ALIGNED_STORAGE
+      data_ = new (&thread_msg_data) LogMessageData;
+#else
+      const uintptr_t kAlign = sizeof(void*) - 1;
+
+      char* align_ptr =
+          reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(thread_msg_data + kAlign) & ~kAlign);
+      data_ = new (align_ptr) LogMessageData;
+      assert(reinterpret_cast<uintptr_t>(align_ptr) % sizeof(void*) == 0);
+#endif
+    } else {
+      allocated_ = new LogMessageData();
+      data_ = allocated_;
+    }
+#else // !defined(GLOG_THREAD_LOCAL_STORAGE)
+    allocated_ = new LogMessageData();
+    data_ = allocated_;
+#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
+    data_->first_fatal_ = false;
+  } else {
+    MutexLock l(&fatal_msg_lock);
+    if (fatal_msg_exclusive) {
+      fatal_msg_exclusive = false;
+      data_ = &fatal_msg_data_exclusive;
+      data_->first_fatal_ = true;
+    } else {
+      data_ = &fatal_msg_data_shared;
+      data_->first_fatal_ = false;
+    }
+  }
+
+  stream().fill('0');
+  data_->preserved_errno_ = errno;
+  data_->severity_ = severity;
+  data_->line_ = line;
+  data_->send_method_ = send_method;
+  data_->sink_ = NULL;
+  data_->outvec_ = NULL;
+  WallTime now = WallTime_Now();
+  data_->timestamp_ = static_cast<time_t>(now);
+  localtime_r(&data_->timestamp_, &data_->tm_time_);
+  int usecs = static_cast<int>((now - data_->timestamp_) * 1000000);
+  RawLog__SetLastTime(data_->tm_time_, usecs);
+
+  data_->num_chars_to_log_ = 0;
+  data_->num_chars_to_syslog_ = 0;
+  data_->basename_ = const_basename(file);
+  data_->fullname_ = file;
+  data_->has_been_flushed_ = false;
+
+  // If specified, prepend a prefix to each line.  For example:
+  //    I1018 160715 f5d4fbb0 logging.cc:1153]
+  //    (log level, GMT month, date, time, thread_id, file basename, line)
+  // We exclude the thread_id for the default thread.
+  if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
+    stream() << LogSeverityNames[severity][0]
+             << setw(2) << 1+data_->tm_time_.tm_mon
+             << setw(2) << data_->tm_time_.tm_mday
+             << ' '
+             << setw(2) << data_->tm_time_.tm_hour  << ':'
+             << setw(2) << data_->tm_time_.tm_min   << ':'
+             << setw(2) << data_->tm_time_.tm_sec   << "."
+             << setw(6) << usecs
+             << ' '
+             << setfill(' ') << setw(5)
+             << static_cast<unsigned int>(GetTID()) << setfill('0')
+             << ' '
+             << data_->basename_ << ':' << data_->line_ << "] ";
+  }
+  data_->num_prefix_chars_ = data_->stream_.pcount();
+
+  if (!FLAGS_log_backtrace_at.empty()) {
+    char fileline[128];
+    snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line);
+#ifdef HAVE_STACKTRACE
+    if (!strcmp(FLAGS_log_backtrace_at.c_str(), fileline)) {
+      string stacktrace;
+      DumpStackTraceToString(&stacktrace);
+      stream() << " (stacktrace:\n" << stacktrace << ") ";
+    }
+#endif
+  }
+}
+
+LogMessage::~LogMessage() {
+  Flush();
+#ifdef GLOG_THREAD_LOCAL_STORAGE
+  if (data_ == static_cast<void*>(&thread_msg_data)) {
+    data_->~LogMessageData();
+    thread_data_available = true;
+  }
+  else {
+    delete allocated_;
+  }
+#else // !defined(GLOG_THREAD_LOCAL_STORAGE)
+  delete allocated_;
+#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
+}
+
+int LogMessage::preserved_errno() const {
+  return data_->preserved_errno_;
+}
+
+ostream& LogMessage::stream() {
+  return data_->stream_;
+}
+
+// Flush buffered message, called by the destructor, or any other function
+// that needs to synchronize the log.
+void LogMessage::Flush() {
+  if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel)
+    return;
+
+  data_->num_chars_to_log_ = data_->stream_.pcount();
+  data_->num_chars_to_syslog_ =
+    data_->num_chars_to_log_ - data_->num_prefix_chars_;
+
+  // Do we need to add a \n to the end of this message?
+  bool append_newline =
+      (data_->message_text_[data_->num_chars_to_log_-1] != '\n');
+  char original_final_char = '\0';
+
+  // If we do need to add a \n, we'll do it by violating the memory of the
+  // ostrstream buffer.  This is quick, and we'll make sure to undo our
+  // modification before anything else is done with the ostrstream.  It
+  // would be preferable not to do things this way, but it seems to be
+  // the best way to deal with this.
+  if (append_newline) {
+    original_final_char = data_->message_text_[data_->num_chars_to_log_];
+    data_->message_text_[data_->num_chars_to_log_++] = '\n';
+  }
+
+  // Prevent any subtle race conditions by wrapping a mutex lock around
+  // the actual logging action per se.
+  {
+    MutexLock l(&log_mutex);
+    (this->*(data_->send_method_))();
+    ++num_messages_[static_cast<int>(data_->severity_)];
+  }
+  LogDestination::WaitForSinks(data_);
+
+  if (append_newline) {
+    // Fix the ostrstream back how it was before we screwed with it.
+    // It's 99.44% certain that we don't need to worry about doing this.
+    data_->message_text_[data_->num_chars_to_log_-1] = original_final_char;
+  }
+
+  // If errno was already set before we enter the logging call, we'll
+  // set it back to that value when we return from the logging call.
+  // It happens often that we log an error message after a syscall
+  // failure, which can potentially set the errno to some other
+  // values.  We would like to preserve the original errno.
+  if (data_->preserved_errno_ != 0) {
+    errno = data_->preserved_errno_;
+  }
+
+  // Note that this message is now safely logged.  If we're asked to flush
+  // again, as a result of destruction, say, we'll do nothing on future calls.
+  data_->has_been_flushed_ = true;
+}
+
+// Copy of first FATAL log message so that we can print it out again
+// after all the stack traces.  To preserve legacy behavior, we don't
+// use fatal_msg_data_exclusive.
+static time_t fatal_time;
+static char fatal_message[256];
+
+void ReprintFatalMessage() {
+  if (fatal_message[0]) {
+    const int n = strlen(fatal_message);
+    if (!FLAGS_logtostderr) {
+      // Also write to stderr (don't color to avoid terminal checks)
+      WriteToStderr(fatal_message, n);
+    }
+    LogDestination::LogToAllLogfiles(GLOG_ERROR, fatal_time, fatal_message, n);
+  }
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+  static bool already_warned_before_initgoogle = false;
+
+  log_mutex.AssertHeld();
+
+  RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
+             data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
+
+  // Messages of a given severity get logged to lower severity logs, too
+
+  if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) {
+    const char w[] = "WARNING: Logging before InitGoogleLogging() is "
+                     "written to STDERR\n";
+    WriteToStderr(w, strlen(w));
+    already_warned_before_initgoogle = true;
+  }
+
+  // global flag: never log to file if set.  Also -- don't log to a
+  // file if we haven't parsed the command line flags to get the
+  // program name.
+  if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) {
+    ColoredWriteToStderr(data_->severity_,
+                         data_->message_text_, data_->num_chars_to_log_);
+
+    // this could be protected by a flag if necessary.
+    LogDestination::LogToSinks(data_->severity_,
+                               data_->fullname_, data_->basename_,
+                               data_->line_, &data_->tm_time_,
+                               data_->message_text_ + data_->num_prefix_chars_,
+                               (data_->num_chars_to_log_ -
+                                data_->num_prefix_chars_ - 1));
+  } else {
+
+    // log this message to all log files of severity <= severity_
+    LogDestination::LogToAllLogfiles(data_->severity_, data_->timestamp_,
+                                     data_->message_text_,
+                                     data_->num_chars_to_log_);
+
+    LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_,
+                                     data_->num_chars_to_log_);
+    LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_,
+                                    data_->num_chars_to_log_);
+    LogDestination::LogToSinks(data_->severity_,
+                               data_->fullname_, data_->basename_,
+                               data_->line_, &data_->tm_time_,
+                               data_->message_text_ + data_->num_prefix_chars_,
+                               (data_->num_chars_to_log_
+                                - data_->num_prefix_chars_ - 1));
+    // NOTE: -1 removes trailing \n
+  }
+
+  // If we log a FATAL message, flush all the log destinations, then toss
+  // a signal for others to catch. We leave the logs in a state that
+  // someone else can use them (as long as they flush afterwards)
+  if (data_->severity_ == GLOG_FATAL && exit_on_dfatal) {
+    if (data_->first_fatal_) {
+      // Store crash information so that it is accessible from within signal
+      // handlers that may be invoked later.
+      RecordCrashReason(&crash_reason);
+      SetCrashReason(&crash_reason);
+
+      // Store shortened fatal message for other logs and GWQ status
+      const int copy = min<int>(data_->num_chars_to_log_,
+                                sizeof(fatal_message)-1);
+      memcpy(fatal_message, data_->message_text_, copy);
+      fatal_message[copy] = '\0';
+      fatal_time = data_->timestamp_;
+    }
+
+    if (!FLAGS_logtostderr) {
+      for (int i = 0; i < NUM_SEVERITIES; ++i) {
+        if ( LogDestination::log_destinations_[i] )
+          LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0);
+      }
+    }
+
+    // release the lock that our caller (directly or indirectly)
+    // LogMessage::~LogMessage() grabbed so that signal handlers
+    // can use the logging facility. Alternately, we could add
+    // an entire unsafe logging interface to bypass locking
+    // for signal handlers but this seems simpler.
+    log_mutex.Unlock();
+    LogDestination::WaitForSinks(data_);
+
+    const char* message = "*** Check failure stack trace: ***\n";
+    if (write(STDERR_FILENO, message, strlen(message)) < 0) {
+      // Ignore errors.
+    }
+    Fail();
+  }
+}
+
+void LogMessage::RecordCrashReason(
+    glog_internal_namespace_::CrashReason* reason) {
+  reason->filename = fatal_msg_data_exclusive.fullname_;
+  reason->line_number = fatal_msg_data_exclusive.line_;
+  reason->message = fatal_msg_data_exclusive.message_text_ +
+                    fatal_msg_data_exclusive.num_prefix_chars_;
+#ifdef HAVE_STACKTRACE
+  // Retrieve the stack trace, omitting the logging frames that got us here.
+  reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4);
+#else
+  reason->depth = 0;
+#endif
+}
+
+#ifdef HAVE___ATTRIBUTE__
+# define ATTRIBUTE_NORETURN __attribute__((noreturn))
+#else
+# define ATTRIBUTE_NORETURN
+#endif
+
+#if defined(OS_WINDOWS)
+__declspec(noreturn)
+#endif
+static void logging_fail() ATTRIBUTE_NORETURN;
+
+static void logging_fail() {
+  abort();
+}
+
+typedef void (*logging_fail_func_t)() ATTRIBUTE_NORETURN;
+
+GOOGLE_GLOG_DLL_DECL
+logging_fail_func_t g_logging_fail_func = &logging_fail;
+
+void InstallFailureFunction(void (*fail_func)()) {
+  g_logging_fail_func = (logging_fail_func_t)fail_func;
+}
+
+void LogMessage::Fail() {
+  g_logging_fail_func();
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+  if (data_->sink_ != NULL) {
+    RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
+               data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
+    data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_,
+                       data_->line_, &data_->tm_time_,
+                       data_->message_text_ + data_->num_prefix_chars_,
+                       (data_->num_chars_to_log_ -
+                        data_->num_prefix_chars_ - 1));
+  }
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+  SendToSink();
+  SendToLog();
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+  if (data_->outvec_ != NULL) {
+    RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
+               data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
+    // Omit prefix of message and trailing newline when recording in outvec_.
+    const char *start = data_->message_text_ + data_->num_prefix_chars_;
+    int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1;
+    data_->outvec_->push_back(string(start, len));
+  } else {
+    SendToLog();
+  }
+}
+
+void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
+  if (data_->message_ != NULL) {
+    RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
+               data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
+    // Omit prefix of message and trailing newline when writing to message_.
+    const char *start = data_->message_text_ + data_->num_prefix_chars_;
+    int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1;
+    data_->message_->assign(start, len);
+  }
+  SendToLog();
+}
+
+// L >= log_mutex (callers must hold the log_mutex).
+void LogMessage::SendToSyslogAndLog() {
+#ifdef HAVE_SYSLOG_H
+  // Before any calls to syslog(), make a single call to openlog()
+  static bool openlog_already_called = false;
+  if (!openlog_already_called) {
+    openlog(glog_internal_namespace_::ProgramInvocationShortName(),
+            LOG_CONS | LOG_NDELAY | LOG_PID,
+            LOG_USER);
+    openlog_already_called = true;
+  }
+
+  // This array maps Google severity levels to syslog levels
+  const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG };
+  syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)], "%.*s",
+         int(data_->num_chars_to_syslog_),
+         data_->message_text_ + data_->num_prefix_chars_);
+  SendToLog();
+#else
+  LOG(ERROR) << "No syslog support: message=" << data_->message_text_;
+#endif
+}
+
+base::Logger* base::GetLogger(LogSeverity severity) {
+  MutexLock l(&log_mutex);
+  return LogDestination::log_destination(severity)->logger_;
+}
+
+void base::SetLogger(LogSeverity severity, base::Logger* logger) {
+  MutexLock l(&log_mutex);
+  LogDestination::log_destination(severity)->logger_ = logger;
+}
+
+// L < log_mutex.  Acquires and releases mutex_.
+int64 LogMessage::num_messages(int severity) {
+  MutexLock l(&log_mutex);
+  return num_messages_[severity];
+}
+
+// Output the COUNTER value. This is only valid if ostream is a
+// LogStream.
+ostream& operator<<(ostream &os, const PRIVATE_Counter&) {
+#ifdef DISABLE_RTTI
+  LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os);
+#else
+  LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os);
+#endif
+  CHECK(log && log == log->self())
+      << "You must not use COUNTER with non-glog ostream";
+  os << log->ctr();
+  return os;
+}
+
+ErrnoLogMessage::ErrnoLogMessage(const char* file, int line,
+                                 LogSeverity severity, int ctr,
+                                 void (LogMessage::*send_method)())
+    : LogMessage(file, line, severity, ctr, send_method) {
+}
+
+ErrnoLogMessage::~ErrnoLogMessage() {
+  // Don't access errno directly because it may have been altered
+  // while streaming the message.
+  stream() << ": " << StrError(preserved_errno()) << " ["
+           << preserved_errno() << "]";
+}
+
+void FlushLogFiles(LogSeverity min_severity) {
+  LogDestination::FlushLogFiles(min_severity);
+}
+
+void FlushLogFilesUnsafe(LogSeverity min_severity) {
+  LogDestination::FlushLogFilesUnsafe(min_severity);
+}
+
+void SetLogDestination(LogSeverity severity, const char* base_filename) {
+  LogDestination::SetLogDestination(severity, base_filename);
+}
+
+void SetLogSymlink(LogSeverity severity, const char* symlink_basename) {
+  LogDestination::SetLogSymlink(severity, symlink_basename);
+}
+
+LogSink::~LogSink() {
+}
+
+void LogSink::WaitTillSent() {
+  // noop default
+}
+
+string LogSink::ToString(LogSeverity severity, const char* file, int line,
+                         const struct ::tm* tm_time,
+                         const char* message, size_t message_len) {
+  ostringstream stream(string(message, message_len));
+  stream.fill('0');
+
+  // FIXME(jrvb): Updating this to use the correct value for usecs
+  // requires changing the signature for both this method and
+  // LogSink::send().  This change needs to be done in a separate CL
+  // so subclasses of LogSink can be updated at the same time.
+  int usecs = 0;
+
+  stream << LogSeverityNames[severity][0]
+         << setw(2) << 1+tm_time->tm_mon
+         << setw(2) << tm_time->tm_mday
+         << ' '
+         << setw(2) << tm_time->tm_hour << ':'
+         << setw(2) << tm_time->tm_min << ':'
+         << setw(2) << tm_time->tm_sec << '.'
+         << setw(6) << usecs
+         << ' '
+         << setfill(' ') << setw(5) << GetTID() << setfill('0')
+         << ' '
+         << file << ':' << line << "] ";
+
+  stream << string(message, message_len);
+  return stream.str();
+}
+
+void AddLogSink(LogSink *destination) {
+  LogDestination::AddLogSink(destination);
+}
+
+void RemoveLogSink(LogSink *destination) {
+  LogDestination::RemoveLogSink(destination);
+}
+
+void SetLogFilenameExtension(const char* ext) {
+  LogDestination::SetLogFilenameExtension(ext);
+}
+
+void SetStderrLogging(LogSeverity min_severity) {
+  LogDestination::SetStderrLogging(min_severity);
+}
+
+void SetEmailLogging(LogSeverity min_severity, const char* addresses) {
+  LogDestination::SetEmailLogging(min_severity, addresses);
+}
+
+void LogToStderr() {
+  LogDestination::LogToStderr();
+}
+
+namespace base {
+namespace internal {
+
+bool GetExitOnDFatal();
+bool GetExitOnDFatal() {
+  MutexLock l(&log_mutex);
+  return exit_on_dfatal;
+}
+
+// Determines whether we exit the program for a LOG(DFATAL) message in
+// debug mode.  It does this by skipping the call to Fail/FailQuietly.
+// This is intended for testing only.
+//
+// This can have some effects on LOG(FATAL) as well.  Failure messages
+// are always allocated (rather than sharing a buffer), the crash
+// reason is not recorded, the "gwq" status message is not updated,
+// and the stack trace is not recorded.  The LOG(FATAL) *will* still
+// exit the program.  Since this function is used only in testing,
+// these differences are acceptable.
+void SetExitOnDFatal(bool value);
+void SetExitOnDFatal(bool value) {
+  MutexLock l(&log_mutex);
+  exit_on_dfatal = value;
+}
+
+}  // namespace internal
+}  // namespace base
+
+// Shell-escaping as we need to shell out ot /bin/mail.
+static const char kDontNeedShellEscapeChars[] =
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+            "abcdefghijklmnopqrstuvwxyz"
+            "0123456789+-_.=/:,@";
+
+static string ShellEscape(const string& src) {
+  string result;
+  if (!src.empty() &&  // empty string needs quotes
+      src.find_first_not_of(kDontNeedShellEscapeChars) == string::npos) {
+    // only contains chars that don't need quotes; it's fine
+    result.assign(src);
+  } else if (src.find_first_of('\'') == string::npos) {
+    // no single quotes; just wrap it in single quotes
+    result.assign("'");
+    result.append(src);
+    result.append("'");
+  } else {
+    // needs double quote escaping
+    result.assign("\"");
+    for (size_t i = 0; i < src.size(); ++i) {
+      switch (src[i]) {
+        case '\\':
+        case '$':
+        case '"':
+        case '`':
+          result.append("\\");
+      }
+      result.append(src, i, 1);
+    }
+    result.append("\"");
+  }
+  return result;
+}
+
+
+// use_logging controls whether the logging functions LOG/VLOG are used
+// to log errors.  It should be set to false when the caller holds the
+// log_mutex.
+static bool SendEmailInternal(const char*dest, const char *subject,
+                              const char*body, bool use_logging) {
+  if (dest && *dest) {
+    if ( use_logging ) {
+      VLOG(1) << "Trying to send TITLE:" << subject
+              << " BODY:" << body << " to " << dest;
+    } else {
+      fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n",
+              subject, body, dest);
+    }
+
+    string cmd =
+        FLAGS_logmailer + " -s" +
+        ShellEscape(subject) + " " + ShellEscape(dest);
+    VLOG(4) << "Mailing command: " << cmd;
+
+    FILE* pipe = popen(cmd.c_str(), "w");
+    if (pipe != NULL) {
+      // Add the body if we have one
+      if (body)
+        fwrite(body, sizeof(char), strlen(body), pipe);
+      bool ok = pclose(pipe) != -1;
+      if ( !ok ) {
+        if ( use_logging ) {
+          LOG(ERROR) << "Problems sending mail to " << dest << ": "
+                     << StrError(errno);
+        } else {
+          fprintf(stderr, "Problems sending mail to %s: %s\n",
+                  dest, StrError(errno).c_str());
+        }
+      }
+      return ok;
+    } else {
+      if ( use_logging ) {
+        LOG(ERROR) << "Unable to send mail to " << dest;
+      } else {
+        fprintf(stderr, "Unable to send mail to %s\n", dest);
+      }
+    }
+  }
+  return false;
+}
+
+bool SendEmail(const char*dest, const char *subject, const char*body){
+  return SendEmailInternal(dest, subject, body, true);
+}
+
+static void GetTempDirectories(vector<string>* list) {
+  list->clear();
+#ifdef OS_WINDOWS
+  // On windows we'll try to find a directory in this order:
+  //   C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is)
+  //   C:/TMP/
+  //   C:/TEMP/
+  //   C:/WINDOWS/ or C:/WINNT/
+  //   .
+  char tmp[MAX_PATH];
+  if (GetTempPathA(MAX_PATH, tmp))
+    list->push_back(tmp);
+  list->push_back("C:\\tmp\\");
+  list->push_back("C:\\temp\\");
+#else
+  // Directories, in order of preference. If we find a dir that
+  // exists, we stop adding other less-preferred dirs
+  const char * candidates[] = {
+    // Non-null only during unittest/regtest
+    getenv("TEST_TMPDIR"),
+
+    // Explicitly-supplied temp dirs
+    getenv("TMPDIR"), getenv("TMP"),
+
+    // If all else fails
+    "/tmp",
+  };
+
+  for (size_t i = 0; i < ARRAYSIZE(candidates); i++) {
+    const char *d = candidates[i];
+    if (!d) continue;  // Empty env var
+
+    // Make sure we don't surprise anyone who's expecting a '/'
+    string dstr = d;
+    if (dstr[dstr.size() - 1] != '/') {
+      dstr += "/";
+    }
+    list->push_back(dstr);
+
+    struct stat statbuf;
+    if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) {
+      // We found a dir that exists - we're done.
+      return;
+    }
+  }
+
+#endif
+}
+
+static vector<string>* logging_directories_list;
+
+const vector<string>& GetLoggingDirectories() {
+  // Not strictly thread-safe but we're called early in InitGoogle().
+  if (logging_directories_list == NULL) {
+    logging_directories_list = new vector<string>;
+
+    if ( !FLAGS_log_dir.empty() ) {
+      // A dir was specified, we should use it
+      logging_directories_list->push_back(FLAGS_log_dir.c_str());
+    } else {
+      GetTempDirectories(logging_directories_list);
+#ifdef OS_WINDOWS
+      char tmp[MAX_PATH];
+      if (GetWindowsDirectoryA(tmp, MAX_PATH))
+        logging_directories_list->push_back(tmp);
+      logging_directories_list->push_back(".\\");
+#else
+      logging_directories_list->push_back("./");
+#endif
+    }
+  }
+  return *logging_directories_list;
+}
+
+void TestOnly_ClearLoggingDirectoriesList() {
+  fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be "
+          "called from test code.\n");
+  delete logging_directories_list;
+  logging_directories_list = NULL;
+}
+
+void GetExistingTempDirectories(vector<string>* list) {
+  GetTempDirectories(list);
+  vector<string>::iterator i_dir = list->begin();
+  while( i_dir != list->end() ) {
+    // zero arg to access means test for existence; no constant
+    // defined on windows
+    if ( access(i_dir->c_str(), 0) ) {
+      i_dir = list->erase(i_dir);
+    } else {
+      ++i_dir;
+    }
+  }
+}
+
+void TruncateLogFile(const char *path, int64 limit, int64 keep) {
+#ifdef HAVE_UNISTD_H
+  struct stat statbuf;
+  const int kCopyBlockSize = 8 << 10;
+  char copybuf[kCopyBlockSize];
+  int64 read_offset, write_offset;
+  // Don't follow symlinks unless they're our own fd symlinks in /proc
+  int flags = O_RDWR;
+  // TODO(hamaji): Support other environments.
+#ifdef OS_LINUX
+  const char *procfd_prefix = "/proc/self/fd/";
+  if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW;
+#endif
+
+  int fd = open(path, flags);
+  if (fd == -1) {
+    if (errno == EFBIG) {
+      // The log file in question has got too big for us to open. The
+      // real fix for this would be to compile logging.cc (or probably
+      // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's
+      // rather scary.
+      // Instead just truncate the file to something we can manage
+      if (truncate(path, 0) == -1) {
+        PLOG(ERROR) << "Unable to truncate " << path;
+      } else {
+        LOG(ERROR) << "Truncated " << path << " due to EFBIG error";
+      }
+    } else {
+      PLOG(ERROR) << "Unable to open " << path;
+    }
+    return;
+  }
+
+  if (fstat(fd, &statbuf) == -1) {
+    PLOG(ERROR) << "Unable to fstat()";
+    goto out_close_fd;
+  }
+
+  // See if the path refers to a regular file bigger than the
+  // specified limit
+  if (!S_ISREG(statbuf.st_mode)) goto out_close_fd;
+  if (statbuf.st_size <= limit)  goto out_close_fd;
+  if (statbuf.st_size <= keep) goto out_close_fd;
+
+  // This log file is too large - we need to truncate it
+  LOG(INFO) << "Truncating " << path << " to " << keep << " bytes";
+
+  // Copy the last "keep" bytes of the file to the beginning of the file
+  read_offset = statbuf.st_size - keep;
+  write_offset = 0;
+  int bytesin, bytesout;
+  while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) {
+    bytesout = pwrite(fd, copybuf, bytesin, write_offset);
+    if (bytesout == -1) {
+      PLOG(ERROR) << "Unable to write to " << path;
+      break;
+    } else if (bytesout != bytesin) {
+      LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout;
+    }
+    read_offset += bytesin;
+    write_offset += bytesout;
+  }
+  if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path;
+
+  // Truncate the remainder of the file. If someone else writes to the
+  // end of the file after our last read() above, we lose their latest
+  // data. Too bad ...
+  if (ftruncate(fd, write_offset) == -1) {
+    PLOG(ERROR) << "Unable to truncate " << path;
+  }
+
+ out_close_fd:
+  close(fd);
+#else
+  LOG(ERROR) << "No log truncation support.";
+  (void)path;
+  (void)limit;
+  (void)keep;
+#endif
+}
+
+void TruncateStdoutStderr() {
+#ifdef HAVE_UNISTD_H
+  int64 limit = MaxLogSize() << 20;
+  int64 keep = 1 << 20;
+  TruncateLogFile("/proc/self/fd/1", limit, keep);
+  TruncateLogFile("/proc/self/fd/2", limit, keep);
+#else
+  LOG(ERROR) << "No log truncation support.";
+#endif
+}
+
+
+// Helper functions for string comparisons.
+#define DEFINE_CHECK_STROP_IMPL(name, func, expected)                   \
+  string* Check##func##expected##Impl(const char* s1, const char* s2,   \
+                                      const char* names) {              \
+    bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2));               \
+    if (equal == expected) return NULL;                                 \
+    else {                                                              \
+      ostringstream ss;                                                 \
+      if (!s1) s1 = "";                                                 \
+      if (!s2) s2 = "";                                                 \
+      ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \
+      return new string(ss.str());                                      \
+    }                                                                   \
+  }
+DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
+DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
+DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true)
+DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
+#undef DEFINE_CHECK_STROP_IMPL
+
+int posix_strerror_r(int err, char *buf, size_t len) {
+  // Sanity check input parameters
+  if (buf == NULL || len <= 0) {
+    errno = EINVAL;
+    return -1;
+  }
+
+  // Reset buf and errno, and try calling whatever version of strerror_r()
+  // is implemented by glibc
+  buf[0] = '\000';
+  int old_errno = errno;
+  errno = 0;
+  char *rc = reinterpret_cast<char *>(strerror_r(err, buf, len));
+
+  // Both versions set errno on failure
+  if (errno) {
+    // Should already be there, but better safe than sorry
+    buf[0]     = '\000';
+    return -1;
+  }
+  errno = old_errno;
+
+  // POSIX is vague about whether the string will be terminated, although
+  // is indirectly implies that typically ERANGE will be returned, instead
+  // of truncating the string. This is different from the GNU implementation.
+  // We play it safe by always terminating the string explicitly.
+  buf[len-1] = '\000';
+
+  // If the function succeeded, we can use its exit code to determine the
+  // semantics implemented by glibc
+  if (!rc) {
+    return 0;
+  } else {
+    // GNU semantics detected
+    if (rc == buf) {
+      return 0;
+    } else {
+      buf[0] = '\000';
+#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD)
+      if (reinterpret_cast<intptr_t>(rc) < sys_nerr) {
+        // This means an error on MacOSX or FreeBSD.
+        return -1;
+      }
+#endif
+      strncat(buf, rc, len-1);
+      return 0;
+    }
+  }
+}
+
+string StrError(int err) {
+  char buf[100];
+  int rc = posix_strerror_r(err, buf, sizeof(buf));
+  if ((rc < 0) || (buf[0] == '\000')) {
+    snprintf(buf, sizeof(buf), "Error number %d", err);
+  }
+  return buf;
+}
+
+LogMessageFatal::LogMessageFatal(const char* file, int line) :
+    LogMessage(file, line, GLOG_FATAL) {}
+
+LogMessageFatal::LogMessageFatal(const char* file, int line,
+                                 const CheckOpString& result) :
+    LogMessage(file, line, result) {}
+
+LogMessageFatal::~LogMessageFatal() {
+    Flush();
+    LogMessage::Fail();
+}
+
+namespace base {
+
+CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext)
+    : stream_(new ostringstream) {
+  *stream_ << exprtext << " (";
+}
+
+CheckOpMessageBuilder::~CheckOpMessageBuilder() {
+  delete stream_;
+}
+
+ostream* CheckOpMessageBuilder::ForVar2() {
+  *stream_ << " vs. ";
+  return stream_;
+}
+
+string* CheckOpMessageBuilder::NewString() {
+  *stream_ << ")";
+  return new string(stream_->str());
+}
+
+}  // namespace base
+
+template <>
+void MakeCheckOpValueString(std::ostream* os, const char& v) {
+  if (v >= 32 && v <= 126) {
+    (*os) << "'" << v << "'";
+  } else {
+    (*os) << "char value " << (short)v;
+  }
+}
+
+template <>
+void MakeCheckOpValueString(std::ostream* os, const signed char& v) {
+  if (v >= 32 && v <= 126) {
+    (*os) << "'" << v << "'";
+  } else {
+    (*os) << "signed char value " << (short)v;
+  }
+}
+
+template <>
+void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) {
+  if (v >= 32 && v <= 126) {
+    (*os) << "'" << v << "'";
+  } else {
+    (*os) << "unsigned char value " << (unsigned short)v;
+  }
+}
+
+void InitGoogleLogging(const char* argv0) {
+  glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
+}
+
+void ShutdownGoogleLogging() {
+  glog_internal_namespace_::ShutdownGoogleLoggingUtilities();
+  LogDestination::DeleteLogDestinations();
+  delete logging_directories_list;
+  logging_directories_list = NULL;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/logging_striplog_test.sh b/third_party/google-glog/src/logging_striplog_test.sh
new file mode 100755
index 0000000..73492bd
--- /dev/null
+++ b/third_party/google-glog/src/logging_striplog_test.sh
@@ -0,0 +1,79 @@
+#! /bin/sh
+#
+# Copyright (c) 2007, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: Sergey Ioffe
+
+get_strings () {
+    if test -e ".libs/$1"; then
+        binary=".libs/$1"
+    elif test -e "$1.exe"; then
+        binary="$1.exe"
+    else
+        echo "We coundn't find $1 binary."
+        exit 1
+    fi
+    
+    strings -n 10 $binary | sort | awk '/TESTMESSAGE/ {printf "%s ", $2}'
+}
+
+# Die if "$1" != "$2", print $3 as death reason
+check_eq () {
+    if [ "$1" != "$2" ]; then
+        echo "Check failed: '$1' == '$2' ${3:+ ($3)}"
+        exit 1
+    fi
+}
+
+die () {
+    echo $1
+    exit 1
+}
+
+# Check that the string literals are appropriately stripped. This will
+# not be the case in debug mode.
+
+mode=`GLOG_check_mode=1 ./logging_striptest0 2> /dev/null`
+if [ "$mode" = "opt" ];
+then
+    echo "In OPT mode"
+    check_eq "`get_strings logging_striptest0`" "COND ERROR FATAL INFO USAGE WARNING "
+    check_eq "`get_strings logging_striptest2`" "COND ERROR FATAL USAGE "
+    check_eq "`get_strings logging_striptest10`" "" 
+else
+    echo "In DBG mode; not checking strings"
+fi
+
+# Check that LOG(FATAL) aborts even for large STRIP_LOG
+
+./logging_striptest2 2>/dev/null && die "Did not abort for STRIP_LOG=2"
+./logging_striptest10 2>/dev/null && die "Did not abort for STRIP_LOG=10"
+
+echo "PASS"
diff --git a/third_party/google-glog/src/logging_striptest10.cc b/third_party/google-glog/src/logging_striptest10.cc
new file mode 100644
index 0000000..f6e1078
--- /dev/null
+++ b/third_party/google-glog/src/logging_striptest10.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sergey Ioffe
+
+#define GOOGLE_STRIP_LOG 10
+
+// Include the actual test.
+#include "logging_striptest_main.cc"
diff --git a/third_party/google-glog/src/logging_striptest2.cc b/third_party/google-glog/src/logging_striptest2.cc
new file mode 100644
index 0000000..a64685c
--- /dev/null
+++ b/third_party/google-glog/src/logging_striptest2.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sergey Ioffe
+
+#define GOOGLE_STRIP_LOG 2
+
+// Include the actual test.
+#include "logging_striptest_main.cc"
diff --git a/third_party/google-glog/src/logging_striptest_main.cc b/third_party/google-glog/src/logging_striptest_main.cc
new file mode 100644
index 0000000..2fb9127
--- /dev/null
+++ b/third_party/google-glog/src/logging_striptest_main.cc
@@ -0,0 +1,73 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Sergey Ioffe
+
+// The common part of the striplog tests.
+
+#include <stdio.h>
+#include <string>
+#include <iosfwd>
+#include "glog/logging.h"
+#include "base/commandlineflags.h"
+#include "config.h"
+
+DECLARE_bool(logtostderr);
+GLOG_DEFINE_bool(check_mode, false, "Prints 'opt' or 'dbg'");
+
+using std::string;
+using namespace GOOGLE_NAMESPACE;
+
+int CheckNoReturn(bool b) {
+  string s;
+  if (b) {
+    LOG(FATAL) << "Fatal";
+  } else {
+    return 0;
+  }
+}
+
+struct A { };
+std::ostream &operator<<(std::ostream &str, const A&) {return str;}
+
+int main(int, char* argv[]) {
+  FLAGS_logtostderr = true;
+  InitGoogleLogging(argv[0]);
+  if (FLAGS_check_mode) {
+    printf("%s\n", DEBUG_MODE ? "dbg" : "opt");
+    return 0;
+  }
+  LOG(INFO) << "TESTMESSAGE INFO";
+  LOG(WARNING) << 2 << "something" << "TESTMESSAGE WARNING"
+               << 1 << 'c' << A() << std::endl;
+  LOG(ERROR) << "TESTMESSAGE ERROR";
+  bool flag = true;
+  (flag ? LOG(INFO) : LOG(ERROR)) << "TESTMESSAGE COND";
+  LOG(FATAL) << "TESTMESSAGE FATAL";
+}
diff --git a/third_party/google-glog/src/logging_unittest.cc b/third_party/google-glog/src/logging_unittest.cc
new file mode 100644
index 0000000..8770d52
--- /dev/null
+++ b/third_party/google-glog/src/logging_unittest.cc
@@ -0,0 +1,1226 @@
+// Copyright (c) 2002, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney
+
+#include "config_for_unittests.h"
+#include "utilities.h"
+
+#include <fcntl.h>
+#ifdef HAVE_GLOB_H
+# include <glob.h>
+#endif
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include <iomanip>
+#include <iostream>
+#include <memory>
+#include <queue>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "base/commandlineflags.h"
+#include "glog/logging.h"
+#include "glog/raw_logging.h"
+#include "googletest.h"
+
+DECLARE_string(log_backtrace_at);  // logging.cc
+
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+using namespace GFLAGS_NAMESPACE;
+#endif
+
+#ifdef HAVE_LIB_GMOCK
+#include <gmock/gmock.h>
+#include "mock-log.h"
+// Introduce several symbols from gmock.
+using testing::_;
+using testing::AnyNumber;
+using testing::HasSubstr;
+using testing::AllOf;
+using testing::StrNe;
+using testing::StrictMock;
+using testing::InitGoogleMock;
+using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
+#endif
+
+using namespace std;
+using namespace GOOGLE_NAMESPACE;
+
+// Some non-advertised functions that we want to test or use.
+_START_GOOGLE_NAMESPACE_
+namespace base {
+namespace internal {
+bool GetExitOnDFatal();
+void SetExitOnDFatal(bool value);
+}  // namespace internal
+}  // namespace base
+_END_GOOGLE_NAMESPACE_
+
+static void TestLogging(bool check_counts);
+static void TestRawLogging();
+static void LogWithLevels(int v, int severity, bool err, bool alsoerr);
+static void TestLoggingLevels();
+static void TestLogString();
+static void TestLogSink();
+static void TestLogToString();
+static void TestLogSinkWaitTillSent();
+static void TestCHECK();
+static void TestDCHECK();
+static void TestSTREQ();
+static void TestBasename();
+static void TestSymlink();
+static void TestExtension();
+static void TestWrapper();
+static void TestErrno();
+static void TestTruncate();
+
+static int x = -1;
+static void BM_Check1(int n) {
+  while (n-- > 0) {
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+    CHECK_GE(n, x);
+  }
+}
+BENCHMARK(BM_Check1);
+
+static void CheckFailure(int a, int b, const char* file, int line, const char* msg);
+static void BM_Check3(int n) {
+  while (n-- > 0) {
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+    if (n < x) CheckFailure(n, x, __FILE__, __LINE__, "n < x");
+  }
+}
+BENCHMARK(BM_Check3);
+
+static void BM_Check2(int n) {
+  if (n == 17) {
+    x = 5;
+  }
+  while (n-- > 0) {
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+    CHECK(n >= x);
+  }
+}
+BENCHMARK(BM_Check2);
+
+static void CheckFailure(int, int, const char* /* file */, int /* line */,
+                         const char* /* msg */) {
+}
+
+static void BM_logspeed(int n) {
+  while (n-- > 0) {
+    LOG(INFO) << "test message";
+  }
+}
+BENCHMARK(BM_logspeed);
+
+static void BM_vlog(int n) {
+  while (n-- > 0) {
+    VLOG(1) << "test message";
+  }
+}
+BENCHMARK(BM_vlog);
+
+int main(int argc, char **argv) {
+  FLAGS_colorlogtostderr = false;
+#ifdef HAVE_LIB_GFLAGS
+  ParseCommandLineFlags(&argc, &argv, true);
+#endif
+  // Make sure stderr is not buffered as stderr seems to be buffered
+  // on recent windows.
+  setbuf(stderr, NULL);
+
+  // Test some basics before InitGoogleLogging:
+  CaptureTestStderr();
+  LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
+                FLAGS_logtostderr, FLAGS_alsologtostderr);
+  LogWithLevels(0, 0, 0, 0);  // simulate "before global c-tors"
+  const string early_stderr = GetCapturedTestStderr();
+
+  InitGoogleLogging(argv[0]);
+
+  RunSpecifiedBenchmarks();
+
+  FLAGS_logtostderr = true;
+
+  InitGoogleTest(&argc, argv);
+#ifdef HAVE_LIB_GMOCK
+  InitGoogleMock(&argc, argv);
+#endif
+
+  // so that death tests run before we use threads
+  CHECK_EQ(RUN_ALL_TESTS(), 0);
+
+  CaptureTestStderr();
+
+  // re-emit early_stderr
+  LogMessage("dummy", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << early_stderr;
+
+  TestLogging(true);
+  TestRawLogging();
+  TestLoggingLevels();
+  TestLogString();
+  TestLogSink();
+  TestLogToString();
+  TestLogSinkWaitTillSent();
+  TestCHECK();
+  TestDCHECK();
+  TestSTREQ();
+
+  // TODO: The golden test portion of this test is very flakey.
+  EXPECT_TRUE(
+      MungeAndDiffTestStderr(FLAGS_test_srcdir + "/src/logging_unittest.err"));
+
+  FLAGS_logtostderr = false;
+
+  TestBasename();
+  TestSymlink();
+  TestExtension();
+  TestWrapper();
+  TestErrno();
+  TestTruncate();
+
+  ShutdownGoogleLogging();
+
+  fprintf(stdout, "PASS\n");
+  return 0;
+}
+
+void TestLogging(bool check_counts) {
+  int64 base_num_infos   = LogMessage::num_messages(GLOG_INFO);
+  int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING);
+  int64 base_num_errors  = LogMessage::num_messages(GLOG_ERROR);
+
+  LOG(INFO) << string("foo ") << "bar " << 10 << ' ' << 3.4;
+  for ( int i = 0; i < 10; ++i ) {
+    int old_errno = errno;
+    errno = i;
+    PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
+    errno = old_errno;
+
+    LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
+    LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;
+
+    LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
+    LOG_IF_EVERY_N(WARNING, false, 3)
+        << "Log if every 3, iteration " << COUNTER;
+    LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
+    LOG_IF_EVERY_N(ERROR, (i < 3), 2)
+        << "Log if less than 3 every 2, iteration " << COUNTER;
+  }
+  LOG_IF(WARNING, true) << "log_if this";
+  LOG_IF(WARNING, false) << "don't log_if this";
+
+  char s[] = "array";
+  LOG(INFO) << s;
+  const char const_s[] = "const array";
+  LOG(INFO) << const_s;
+  int j = 1000;
+  LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
+             << setw(1) << hex << j;
+
+  {
+    google::LogMessage outer(__FILE__, __LINE__, GLOG_ERROR);
+    outer.stream() << "outer";
+
+    LOG(ERROR) << "inner";
+  }
+
+  LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
+
+  if (check_counts) {
+    CHECK_EQ(base_num_infos   + 14, LogMessage::num_messages(GLOG_INFO));
+    CHECK_EQ(base_num_warning + 3,  LogMessage::num_messages(GLOG_WARNING));
+    CHECK_EQ(base_num_errors  + 17, LogMessage::num_messages(GLOG_ERROR));
+  }
+}
+
+static void NoAllocNewHook() {
+  LOG(FATAL) << "unexpected new";
+}
+
+struct NewHook {
+  NewHook() {
+    g_new_hook = &NoAllocNewHook;
+  }
+  ~NewHook() {
+    g_new_hook = NULL;
+  }
+};
+
+TEST(DeathNoAllocNewHook, logging) {
+  // tests that NewHook used below works
+  NewHook new_hook;
+  ASSERT_DEATH({
+    new int;
+  }, "unexpected new");
+}
+
+void TestRawLogging() {
+  string* foo = new string("foo ");
+  string huge_str(50000, 'a');
+
+  FlagSaver saver;
+
+  // Check that RAW loggging does not use mallocs.
+  NewHook new_hook;
+
+  RAW_LOG(INFO, "%s%s%d%c%f", foo->c_str(), "bar ", 10, ' ', 3.4);
+  char s[] = "array";
+  RAW_LOG(WARNING, "%s", s);
+  const char const_s[] = "const array";
+  RAW_LOG(INFO, "%s", const_s);
+  void* p = reinterpret_cast<void*>(PTR_TEST_VALUE);
+  RAW_LOG(INFO, "ptr %p", p);
+  p = NULL;
+  RAW_LOG(INFO, "ptr %p", p);
+  int j = 1000;
+  RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
+  RAW_VLOG(0, "foo %d", j);
+
+#ifdef NDEBUG
+  RAW_LOG(INFO, "foo %d", j);  // so that have same stderr to compare
+#else
+  RAW_DLOG(INFO, "foo %d", j);  // test RAW_DLOG in debug mode
+#endif
+
+  // test how long messages are chopped:
+  RAW_LOG(WARNING, "Huge string: %s", huge_str.c_str());
+  RAW_VLOG(0, "Huge string: %s", huge_str.c_str());
+
+  FLAGS_v = 0;
+  RAW_LOG(INFO, "log");
+  RAW_VLOG(0, "vlog 0 on");
+  RAW_VLOG(1, "vlog 1 off");
+  RAW_VLOG(2, "vlog 2 off");
+  RAW_VLOG(3, "vlog 3 off");
+  FLAGS_v = 2;
+  RAW_LOG(INFO, "log");
+  RAW_VLOG(1, "vlog 1 on");
+  RAW_VLOG(2, "vlog 2 on");
+  RAW_VLOG(3, "vlog 3 off");
+
+#ifdef NDEBUG
+  RAW_DCHECK(1 == 2, " RAW_DCHECK's shouldn't be compiled in normal mode");
+#endif
+
+  RAW_CHECK(1 == 1, "should be ok");
+  RAW_DCHECK(true, "should be ok");
+
+  delete foo;
+}
+
+void LogWithLevels(int v, int severity, bool err, bool alsoerr) {
+  RAW_LOG(INFO,
+          "Test: v=%d stderrthreshold=%d logtostderr=%d alsologtostderr=%d",
+          v, severity, err, alsoerr);
+
+  FlagSaver saver;
+
+  FLAGS_v = v;
+  FLAGS_stderrthreshold = severity;
+  FLAGS_logtostderr = err;
+  FLAGS_alsologtostderr = alsoerr;
+
+  RAW_VLOG(-1, "vlog -1");
+  RAW_VLOG(0, "vlog 0");
+  RAW_VLOG(1, "vlog 1");
+  RAW_LOG(INFO, "log info");
+  RAW_LOG(WARNING, "log warning");
+  RAW_LOG(ERROR, "log error");
+
+  VLOG(-1) << "vlog -1";
+  VLOG(0) << "vlog 0";
+  VLOG(1) << "vlog 1";
+  LOG(INFO) << "log info";
+  LOG(WARNING) << "log warning";
+  LOG(ERROR) << "log error";
+
+  VLOG_IF(-1, true) << "vlog_if -1";
+  VLOG_IF(-1, false) << "don't vlog_if -1";
+  VLOG_IF(0, true) << "vlog_if 0";
+  VLOG_IF(0, false) << "don't vlog_if 0";
+  VLOG_IF(1, true) << "vlog_if 1";
+  VLOG_IF(1, false) << "don't vlog_if 1";
+  LOG_IF(INFO, true) << "log_if info";
+  LOG_IF(INFO, false) << "don't log_if info";
+  LOG_IF(WARNING, true) << "log_if warning";
+  LOG_IF(WARNING, false) << "don't log_if warning";
+  LOG_IF(ERROR, true) << "log_if error";
+  LOG_IF(ERROR, false) << "don't log_if error";
+
+  int c;
+  c = 1; VLOG_IF(100, c -= 2) << "vlog_if 100 expr"; EXPECT_EQ(c, -1);
+  c = 1; VLOG_IF(0, c -= 2) << "vlog_if 0 expr"; EXPECT_EQ(c, -1);
+  c = 1; LOG_IF(INFO, c -= 2) << "log_if info expr"; EXPECT_EQ(c, -1);
+  c = 1; LOG_IF(ERROR, c -= 2) << "log_if error expr"; EXPECT_EQ(c, -1);
+  c = 2; VLOG_IF(0, c -= 2) << "don't vlog_if 0 expr"; EXPECT_EQ(c, 0);
+  c = 2; LOG_IF(ERROR, c -= 2) << "don't log_if error expr"; EXPECT_EQ(c, 0);
+
+  c = 3; LOG_IF_EVERY_N(INFO, c -= 4, 1) << "log_if info every 1 expr";
+  EXPECT_EQ(c, -1);
+  c = 3; LOG_IF_EVERY_N(ERROR, c -= 4, 1) << "log_if error every 1 expr";
+  EXPECT_EQ(c, -1);
+  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if info every 3 expr";
+  EXPECT_EQ(c, 0);
+  c = 4; LOG_IF_EVERY_N(ERROR, c -= 4, 3) << "don't log_if error every 3 expr";
+  EXPECT_EQ(c, 0);
+  c = 5; VLOG_IF_EVERY_N(0, c -= 4, 1) << "vlog_if 0 every 1 expr";
+  EXPECT_EQ(c, 1);
+  c = 5; VLOG_IF_EVERY_N(100, c -= 4, 3) << "vlog_if 100 every 3 expr";
+  EXPECT_EQ(c, 1);
+  c = 6; VLOG_IF_EVERY_N(0, c -= 6, 1) << "don't vlog_if 0 every 1 expr";
+  EXPECT_EQ(c, 0);
+  c = 6; VLOG_IF_EVERY_N(100, c -= 6, 3) << "don't vlog_if 100 every 1 expr";
+  EXPECT_EQ(c, 0);
+}
+
+void TestLoggingLevels() {
+  LogWithLevels(0, GLOG_INFO, false, false);
+  LogWithLevels(1, GLOG_INFO, false, false);
+  LogWithLevels(-1, GLOG_INFO, false, false);
+  LogWithLevels(0, GLOG_WARNING, false, false);
+  LogWithLevels(0, GLOG_ERROR, false, false);
+  LogWithLevels(0, GLOG_FATAL, false, false);
+  LogWithLevels(0, GLOG_FATAL, true, false);
+  LogWithLevels(0, GLOG_FATAL, false, true);
+  LogWithLevels(1, GLOG_WARNING, false, false);
+  LogWithLevels(1, GLOG_FATAL, false, true);
+}
+
+TEST(DeathRawCHECK, logging) {
+  ASSERT_DEATH(RAW_CHECK(false, "failure 1"),
+               "RAW: Check false failed: failure 1");
+  ASSERT_DEBUG_DEATH(RAW_DCHECK(1 == 2, "failure 2"),
+               "RAW: Check 1 == 2 failed: failure 2");
+}
+
+void TestLogString() {
+  vector<string> errors;
+  vector<string> *no_errors = NULL;
+
+  LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
+  LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
+  LOG_STRING(ERROR, &errors) << "LOG_STRING: " << "collected error";
+
+  LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
+  LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
+  LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error";
+
+  for (size_t i = 0; i < errors.size(); ++i) {
+    LOG(INFO) << "Captured by LOG_STRING:  " << errors[i];
+  }
+}
+
+void TestLogToString() {
+  string error;
+  string* no_error = NULL;
+
+  LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
+  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
+  LOG_TO_STRING(WARNING, &error) << "LOG_TO_STRING: " << "collected warning";
+  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
+  LOG_TO_STRING(ERROR, &error) << "LOG_TO_STRING: " << "collected error";
+  LOG(INFO) << "Captured by LOG_TO_STRING:  " << error;
+
+  LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
+  LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
+  LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error";
+}
+
+class TestLogSinkImpl : public LogSink {
+ public:
+  vector<string> errors;
+  virtual void send(LogSeverity severity, const char* /* full_filename */,
+                    const char* base_filename, int line,
+                    const struct tm* tm_time,
+                    const char* message, size_t message_len) {
+    errors.push_back(
+      ToString(severity, base_filename, line, tm_time, message, message_len));
+  }
+};
+
+void TestLogSink() {
+  TestLogSinkImpl sink;
+  LogSink *no_sink = NULL;
+
+  LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
+  LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
+  LOG_TO_SINK(&sink, ERROR) << "LOG_TO_SINK: " << "collected error";
+
+  LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
+  LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
+  LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error";
+
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, WARNING)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected warning";
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, ERROR)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected error";
+
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, INFO)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
+  LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR)
+      << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error";
+
+  LOG(INFO) << "Captured by LOG_TO_SINK:";
+  for (size_t i = 0; i < sink.errors.size(); ++i) {
+    LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream()
+      << sink.errors[i];
+  }
+}
+
+// For testing using CHECK*() on anonymous enums.
+enum {
+  CASE_A,
+  CASE_B
+};
+
+void TestCHECK() {
+  // Tests using CHECK*() on int values.
+  CHECK(1 == 1);
+  CHECK_EQ(1, 1);
+  CHECK_NE(1, 2);
+  CHECK_GE(1, 1);
+  CHECK_GE(2, 1);
+  CHECK_LE(1, 1);
+  CHECK_LE(1, 2);
+  CHECK_GT(2, 1);
+  CHECK_LT(1, 2);
+
+  // Tests using CHECK*() on anonymous enums.
+  // Apple's GCC doesn't like this.
+#if !defined(OS_MACOSX)
+  CHECK_EQ(CASE_A, CASE_A);
+  CHECK_NE(CASE_A, CASE_B);
+  CHECK_GE(CASE_A, CASE_A);
+  CHECK_GE(CASE_B, CASE_A);
+  CHECK_LE(CASE_A, CASE_A);
+  CHECK_LE(CASE_A, CASE_B);
+  CHECK_GT(CASE_B, CASE_A);
+  CHECK_LT(CASE_A, CASE_B);
+#endif
+}
+
+void TestDCHECK() {
+#ifdef NDEBUG
+  DCHECK( 1 == 2 ) << " DCHECK's shouldn't be compiled in normal mode";
+#endif
+  DCHECK( 1 == 1 );
+  DCHECK_EQ(1, 1);
+  DCHECK_NE(1, 2);
+  DCHECK_GE(1, 1);
+  DCHECK_GE(2, 1);
+  DCHECK_LE(1, 1);
+  DCHECK_LE(1, 2);
+  DCHECK_GT(2, 1);
+  DCHECK_LT(1, 2);
+
+  auto_ptr<int64> sptr(new int64);
+  int64* ptr = DCHECK_NOTNULL(sptr.get());
+  CHECK_EQ(ptr, sptr.get());
+}
+
+void TestSTREQ() {
+  CHECK_STREQ("this", "this");
+  CHECK_STREQ(NULL, NULL);
+  CHECK_STRCASEEQ("this", "tHiS");
+  CHECK_STRCASEEQ(NULL, NULL);
+  CHECK_STRNE("this", "tHiS");
+  CHECK_STRNE("this", NULL);
+  CHECK_STRCASENE("this", "that");
+  CHECK_STRCASENE(NULL, "that");
+  CHECK_STREQ((string("a")+"b").c_str(), "ab");
+  CHECK_STREQ(string("test").c_str(),
+              (string("te") + string("st")).c_str());
+}
+
+TEST(DeathSTREQ, logging) {
+  ASSERT_DEATH(CHECK_STREQ(NULL, "this"), "");
+  ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
+  ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), "");
+  ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
+  ASSERT_DEATH(CHECK_STRNE(NULL, NULL), "");
+  ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
+  ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
+}
+
+TEST(CheckNOTNULL, Simple) {
+  int64 t;
+  void *ptr = static_cast<void *>(&t);
+  void *ref = CHECK_NOTNULL(ptr);
+  EXPECT_EQ(ptr, ref);
+  CHECK_NOTNULL(reinterpret_cast<char *>(ptr));
+  CHECK_NOTNULL(reinterpret_cast<unsigned char *>(ptr));
+  CHECK_NOTNULL(reinterpret_cast<int *>(ptr));
+  CHECK_NOTNULL(reinterpret_cast<int64 *>(ptr));
+}
+
+TEST(DeathCheckNN, Simple) {
+  ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), "");
+}
+
+// Get list of file names that match pattern
+static void GetFiles(const string& pattern, vector<string>* files) {
+  files->clear();
+#if defined(HAVE_GLOB_H)
+  glob_t g;
+  const int r = glob(pattern.c_str(), 0, NULL, &g);
+  CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
+  for (size_t i = 0; i < g.gl_pathc; i++) {
+    files->push_back(string(g.gl_pathv[i]));
+  }
+  globfree(&g);
+#elif defined(OS_WINDOWS)
+  WIN32_FIND_DATAA data;
+  HANDLE handle = FindFirstFileA(pattern.c_str(), &data);
+  size_t index = pattern.rfind('\\');
+  if (index == string::npos) {
+    LOG(FATAL) << "No directory separator.";
+  }
+  const string dirname = pattern.substr(0, index + 1);
+  if (handle == INVALID_HANDLE_VALUE) {
+    // Finding no files is OK.
+    return;
+  }
+  do {
+    files->push_back(dirname + data.cFileName);
+  } while (FindNextFileA(handle, &data));
+  BOOL result = FindClose(handle);
+  LOG_SYSRESULT(result);
+#else
+# error There is no way to do glob.
+#endif
+}
+
+// Delete files patching pattern
+static void DeleteFiles(const string& pattern) {
+  vector<string> files;
+  GetFiles(pattern, &files);
+  for (size_t i = 0; i < files.size(); i++) {
+    CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno);
+  }
+}
+
+static void CheckFile(const string& name, const string& expected_string) {
+  vector<string> files;
+  GetFiles(name + "*", &files);
+  CHECK_EQ(files.size(), 1UL);
+
+  FILE* file = fopen(files[0].c_str(), "r");
+  CHECK(file != NULL) << ": could not open " << files[0];
+  char buf[1000];
+  while (fgets(buf, sizeof(buf), file) != NULL) {
+    if (strstr(buf, expected_string.c_str()) != NULL) {
+      fclose(file);
+      return;
+    }
+  }
+  fclose(file);
+  LOG(FATAL) << "Did not find " << expected_string << " in " << files[0];
+}
+
+static void TestBasename() {
+  fprintf(stderr, "==== Test setting log file basename\n");
+  const string dest = FLAGS_test_tmpdir + "/logging_test_basename";
+  DeleteFiles(dest + "*");
+
+  SetLogDestination(GLOG_INFO, dest.c_str());
+  LOG(INFO) << "message to new base";
+  FlushLogFiles(GLOG_INFO);
+
+  CheckFile(dest, "message to new base");
+
+  // Release file handle for the destination file to unlock the file in Windows.
+  LogToStderr();
+  DeleteFiles(dest + "*");
+}
+
+static void TestSymlink() {
+#ifndef OS_WINDOWS
+  fprintf(stderr, "==== Test setting log file symlink\n");
+  string dest = FLAGS_test_tmpdir + "/logging_test_symlink";
+  string sym = FLAGS_test_tmpdir + "/symlinkbase";
+  DeleteFiles(dest + "*");
+  DeleteFiles(sym + "*");
+
+  SetLogSymlink(GLOG_INFO, "symlinkbase");
+  SetLogDestination(GLOG_INFO, dest.c_str());
+  LOG(INFO) << "message to new symlink";
+  FlushLogFiles(GLOG_INFO);
+  CheckFile(sym, "message to new symlink");
+
+  DeleteFiles(dest + "*");
+  DeleteFiles(sym + "*");
+#endif
+}
+
+static void TestExtension() {
+  fprintf(stderr, "==== Test setting log file extension\n");
+  string dest = FLAGS_test_tmpdir + "/logging_test_extension";
+  DeleteFiles(dest + "*");
+
+  SetLogDestination(GLOG_INFO, dest.c_str());
+  SetLogFilenameExtension("specialextension");
+  LOG(INFO) << "message to new extension";
+  FlushLogFiles(GLOG_INFO);
+  CheckFile(dest, "message to new extension");
+
+  // Check that file name ends with extension
+  vector<string> filenames;
+  GetFiles(dest + "*", &filenames);
+  CHECK_EQ(filenames.size(), 1UL);
+  CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL);
+
+  // Release file handle for the destination file to unlock the file in Windows.
+  LogToStderr();
+  DeleteFiles(dest + "*");
+}
+
+struct MyLogger : public base::Logger {
+  string data;
+
+  virtual void Write(bool /* should_flush */,
+                     time_t /* timestamp */,
+                     const char* message,
+                     int length) {
+    data.append(message, length);
+  }
+
+  virtual void Flush() { }
+
+  virtual uint32 LogSize() { return data.length(); }
+};
+
+static void TestWrapper() {
+  fprintf(stderr, "==== Test log wrapper\n");
+
+  MyLogger my_logger;
+  base::Logger* old_logger = base::GetLogger(GLOG_INFO);
+  base::SetLogger(GLOG_INFO, &my_logger);
+  LOG(INFO) << "Send to wrapped logger";
+  FlushLogFiles(GLOG_INFO);
+  base::SetLogger(GLOG_INFO, old_logger);
+
+  CHECK(strstr(my_logger.data.c_str(), "Send to wrapped logger") != NULL);
+}
+
+static void TestErrno() {
+  fprintf(stderr, "==== Test errno preservation\n");
+
+  errno = ENOENT;
+  TestLogging(false);
+  CHECK_EQ(errno, ENOENT);
+}
+
+static void TestOneTruncate(const char *path, int64 limit, int64 keep,
+                            int64 dsize, int64 ksize, int64 expect) {
+  int fd;
+  CHECK_ERR(fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600));
+
+  const char *discardstr = "DISCARDME!", *keepstr = "KEEPME!";
+  const size_t discard_size = strlen(discardstr), keep_size = strlen(keepstr);
+
+  // Fill the file with the requested data; first discard data, then kept data
+  int64 written = 0;
+  while (written < dsize) {
+    int bytes = min<int64>(dsize - written, discard_size);
+    CHECK_ERR(write(fd, discardstr, bytes));
+    written += bytes;
+  }
+  written = 0;
+  while (written < ksize) {
+    int bytes = min<int64>(ksize - written, keep_size);
+    CHECK_ERR(write(fd, keepstr, bytes));
+    written += bytes;
+  }
+
+  TruncateLogFile(path, limit, keep);
+
+  // File should now be shorter
+  struct stat statbuf;
+  CHECK_ERR(fstat(fd, &statbuf));
+  CHECK_EQ(statbuf.st_size, expect);
+  CHECK_ERR(lseek(fd, 0, SEEK_SET));
+
+  // File should contain the suffix of the original file
+  const size_t buf_size = statbuf.st_size + 1;
+  char* buf = new char[buf_size];
+  memset(buf, 0, buf_size);
+  CHECK_ERR(read(fd, buf, buf_size));
+
+  const char *p = buf;
+  int64 checked = 0;
+  while (checked < expect) {
+    int bytes = min<int64>(expect - checked, keep_size);
+    CHECK(!memcmp(p, keepstr, bytes));
+    checked += bytes;
+  }
+  close(fd);
+  delete[] buf;
+}
+
+static void TestTruncate() {
+#ifdef HAVE_UNISTD_H
+  fprintf(stderr, "==== Test log truncation\n");
+  string path = FLAGS_test_tmpdir + "/truncatefile";
+
+  // Test on a small file
+  TestOneTruncate(path.c_str(), 10, 10, 10, 10, 10);
+
+  // And a big file (multiple blocks to copy)
+  TestOneTruncate(path.c_str(), 2<<20, 4<<10, 3<<20, 4<<10, 4<<10);
+
+  // Check edge-case limits
+  TestOneTruncate(path.c_str(), 10, 20, 0, 20, 20);
+  TestOneTruncate(path.c_str(), 10, 0, 0, 0, 0);
+  TestOneTruncate(path.c_str(), 10, 50, 0, 10, 10);
+  TestOneTruncate(path.c_str(), 50, 100, 0, 30, 30);
+
+  // MacOSX 10.4 doesn't fail in this case.
+  // Windows doesn't have symlink.
+  // Let's just ignore this test for these cases.
+#if !defined(OS_MACOSX) && !defined(OS_WINDOWS)
+  // Through a symlink should fail to truncate
+  string linkname = path + ".link";
+  unlink(linkname.c_str());
+  CHECK_ERR(symlink(path.c_str(), linkname.c_str()));
+  TestOneTruncate(linkname.c_str(), 10, 10, 0, 30, 30);
+#endif
+
+  // The /proc/self path makes sense only for linux.
+#if defined(OS_LINUX)
+  // Through an open fd symlink should work
+  int fd;
+  CHECK_ERR(fd = open(path.c_str(), O_APPEND | O_WRONLY));
+  char fdpath[64];
+  snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
+  TestOneTruncate(fdpath, 10, 10, 10, 10, 10);
+#endif
+
+#endif
+}
+
+_START_GOOGLE_NAMESPACE_
+namespace glog_internal_namespace_ {
+extern  // in logging.cc
+bool SafeFNMatch_(const char* pattern, size_t patt_len,
+                  const char* str, size_t str_len);
+} // namespace glog_internal_namespace_
+using glog_internal_namespace_::SafeFNMatch_;
+_END_GOOGLE_NAMESPACE_
+
+static bool WrapSafeFNMatch(string pattern, string str) {
+  pattern += "abc";
+  str += "defgh";
+  return SafeFNMatch_(pattern.data(), pattern.size() - 3,
+                      str.data(), str.size() - 5);
+}
+
+TEST(SafeFNMatch, logging) {
+  CHECK(WrapSafeFNMatch("foo", "foo"));
+  CHECK(!WrapSafeFNMatch("foo", "bar"));
+  CHECK(!WrapSafeFNMatch("foo", "fo"));
+  CHECK(!WrapSafeFNMatch("foo", "foo2"));
+  CHECK(WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext"));
+  CHECK(WrapSafeFNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"));
+  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/baz.ext"));
+  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo"));
+  CHECK(!WrapSafeFNMatch("bar/foo.ext", "bar/foo.ext.zip"));
+  CHECK(WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext"));
+  CHECK(WrapSafeFNMatch("ba?/*.ext", "baZ/FOO.ext"));
+  CHECK(!WrapSafeFNMatch("ba?/*.ext", "barr/foo.ext"));
+  CHECK(!WrapSafeFNMatch("ba?/*.ext", "bar/foo.ext2"));
+  CHECK(WrapSafeFNMatch("ba?/*", "bar/foo.ext2"));
+  CHECK(WrapSafeFNMatch("ba?/*", "bar/"));
+  CHECK(!WrapSafeFNMatch("ba?/?", "bar/"));
+  CHECK(!WrapSafeFNMatch("ba?/*", "bar"));
+}
+
+// TestWaitingLogSink will save messages here
+// No lock: Accessed only by TestLogSinkWriter thread
+// and after its demise by its creator.
+static vector<string> global_messages;
+
+// helper for TestWaitingLogSink below.
+// Thread that does the logic of TestWaitingLogSink
+// It's free to use LOG() itself.
+class TestLogSinkWriter : public Thread {
+ public:
+
+  TestLogSinkWriter() : should_exit_(false) {
+    SetJoinable(true);
+    Start();
+  }
+
+  // Just buffer it (can't use LOG() here).
+  void Buffer(const string& message) {
+    mutex_.Lock();
+    RAW_LOG(INFO, "Buffering");
+    messages_.push(message);
+    mutex_.Unlock();
+    RAW_LOG(INFO, "Buffered");
+  }
+
+  // Wait for the buffer to clear (can't use LOG() here).
+  void Wait() {
+    RAW_LOG(INFO, "Waiting");
+    mutex_.Lock();
+    while (!NoWork()) {
+      mutex_.Unlock();
+      SleepForMilliseconds(1);
+      mutex_.Lock();
+    }
+    RAW_LOG(INFO, "Waited");
+    mutex_.Unlock();
+  }
+
+  // Trigger thread exit.
+  void Stop() {
+    MutexLock l(&mutex_);
+    should_exit_ = true;
+  }
+
+ private:
+
+  // helpers ---------------
+
+  // For creating a "Condition".
+  bool NoWork() { return messages_.empty(); }
+  bool HaveWork() { return !messages_.empty() || should_exit_; }
+
+  // Thread body; CAN use LOG() here!
+  virtual void Run() {
+    while (1) {
+      mutex_.Lock();
+      while (!HaveWork()) {
+        mutex_.Unlock();
+        SleepForMilliseconds(1);
+        mutex_.Lock();
+      }
+      if (should_exit_ && messages_.empty()) {
+        mutex_.Unlock();
+        break;
+      }
+      // Give the main thread time to log its message,
+      // so that we get a reliable log capture to compare to golden file.
+      // Same for the other sleep below.
+      SleepForMilliseconds(20);
+      RAW_LOG(INFO, "Sink got a messages");  // only RAW_LOG under mutex_ here
+      string message = messages_.front();
+      messages_.pop();
+      // Normally this would be some more real/involved logging logic
+      // where LOG() usage can't be eliminated,
+      // e.g. pushing the message over with an RPC:
+      int messages_left = messages_.size();
+      mutex_.Unlock();
+      SleepForMilliseconds(20);
+      // May not use LOG while holding mutex_, because Buffer()
+      // acquires mutex_, and Buffer is called from LOG(),
+      // which has its own internal mutex:
+      // LOG()->LogToSinks()->TestWaitingLogSink::send()->Buffer()
+      LOG(INFO) << "Sink is sending out a message: " << message;
+      LOG(INFO) << "Have " << messages_left << " left";
+      global_messages.push_back(message);
+    }
+  }
+
+  // data ---------------
+
+  Mutex mutex_;
+  bool should_exit_;
+  queue<string> messages_;  // messages to be logged
+};
+
+// A log sink that exercises WaitTillSent:
+// it pushes data to a buffer and wakes up another thread to do the logging
+// (that other thread can than use LOG() itself),
+class TestWaitingLogSink : public LogSink {
+ public:
+
+  TestWaitingLogSink() {
+    tid_ = pthread_self();  // for thread-specific behavior
+    AddLogSink(this);
+  }
+  ~TestWaitingLogSink() {
+    RemoveLogSink(this);
+    writer_.Stop();
+    writer_.Join();
+  }
+
+  // (re)define LogSink interface
+
+  virtual void send(LogSeverity severity, const char* /* full_filename */,
+                    const char* base_filename, int line,
+                    const struct tm* tm_time,
+                    const char* message, size_t message_len) {
+    // Push it to Writer thread if we are the original logging thread.
+    // Note: Something like ThreadLocalLogSink is a better choice
+    //       to do thread-specific LogSink logic for real.
+    if (pthread_equal(tid_, pthread_self())) {
+      writer_.Buffer(ToString(severity, base_filename, line,
+                              tm_time, message, message_len));
+    }
+  }
+  virtual void WaitTillSent() {
+    // Wait for Writer thread if we are the original logging thread.
+    if (pthread_equal(tid_, pthread_self()))  writer_.Wait();
+  }
+
+ private:
+
+  pthread_t tid_;
+  TestLogSinkWriter writer_;
+};
+
+// Check that LogSink::WaitTillSent can be used in the advertised way.
+// We also do golden-stderr comparison.
+static void TestLogSinkWaitTillSent() {
+  { TestWaitingLogSink sink;
+    // Sleeps give the sink threads time to do all their work,
+    // so that we get a reliable log capture to compare to the golden file.
+    LOG(INFO) << "Message 1";
+    SleepForMilliseconds(60);
+    LOG(ERROR) << "Message 2";
+    SleepForMilliseconds(60);
+    LOG(WARNING) << "Message 3";
+    SleepForMilliseconds(60);
+  }
+  for (size_t i = 0; i < global_messages.size(); ++i) {
+    LOG(INFO) << "Sink capture: " << global_messages[i];
+  }
+  CHECK_EQ(global_messages.size(), 3UL);
+}
+
+TEST(Strerror, logging) {
+  int errcode = EINTR;
+  char *msg = strdup(strerror(errcode));
+  const size_t buf_size = strlen(msg) + 1;
+  char *buf = new char[buf_size];
+  CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1);
+  buf[0] = 'A';
+  CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
+  CHECK_EQ(buf[0], 'A');
+  CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1);
+#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD)
+  // MacOSX or FreeBSD considers this case is an error since there is
+  // no enough space.
+  CHECK_EQ(posix_strerror_r(errcode, buf, 1), -1);
+#else
+  CHECK_EQ(posix_strerror_r(errcode, buf, 1), 0);
+#endif
+  CHECK_STREQ(buf, "");
+  CHECK_EQ(posix_strerror_r(errcode, buf, buf_size), 0);
+  CHECK_STREQ(buf, msg);
+  delete[] buf;
+  CHECK_EQ(msg, StrError(errcode));
+  free(msg);
+}
+
+// Simple routines to look at the sizes of generated code for LOG(FATAL) and
+// CHECK(..) via objdump
+static void MyFatal() {
+  LOG(FATAL) << "Failed";
+}
+static void MyCheck(bool a, bool b) {
+  CHECK_EQ(a, b);
+}
+
+#ifdef HAVE_LIB_GMOCK
+
+TEST(DVLog, Basic) {
+  ScopedMockLog log;
+
+#if NDEBUG
+  // We are expecting that nothing is logged.
+  EXPECT_CALL(log, Log(_, _, _)).Times(0);
+#else
+  EXPECT_CALL(log, Log(INFO, __FILE__, "debug log"));
+#endif
+
+  FLAGS_v = 1;
+  DVLOG(1) << "debug log";
+}
+
+TEST(DVLog, V0) {
+  ScopedMockLog log;
+
+  // We are expecting that nothing is logged.
+  EXPECT_CALL(log, Log(_, _, _)).Times(0);
+
+  FLAGS_v = 0;
+  DVLOG(1) << "debug log";
+}
+
+TEST(LogAtLevel, Basic) {
+  ScopedMockLog log;
+
+  // The function version outputs "logging.h" as a file name.
+  EXPECT_CALL(log, Log(WARNING, StrNe(__FILE__), "function version"));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "macro version"));
+
+  int severity = WARNING;
+  LogAtLevel(severity, "function version");
+
+  severity = INFO;
+  // We can use the macro version as a C++ stream.
+  LOG_AT_LEVEL(severity) << "macro" << ' ' << "version";
+}
+
+TEST(TestExitOnDFatal, ToBeOrNotToBe) {
+  // Check the default setting...
+  EXPECT_TRUE(base::internal::GetExitOnDFatal());
+
+  // Turn off...
+  base::internal::SetExitOnDFatal(false);
+  EXPECT_FALSE(base::internal::GetExitOnDFatal());
+
+  // We don't die.
+  {
+    ScopedMockLog log;
+    //EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
+    // LOG(DFATAL) has severity FATAL if debugging, but is
+    // downgraded to ERROR if not debugging.
+    const LogSeverity severity =
+#ifdef NDEBUG
+        ERROR;
+#else
+        FATAL;
+#endif
+    EXPECT_CALL(log, Log(severity, __FILE__, "This should not be fatal"));
+    LOG(DFATAL) << "This should not be fatal";
+  }
+
+  // Turn back on...
+  base::internal::SetExitOnDFatal(true);
+  EXPECT_TRUE(base::internal::GetExitOnDFatal());
+
+#ifdef GTEST_HAS_DEATH_TEST
+  // Death comes on little cats' feet.
+  EXPECT_DEBUG_DEATH({
+      LOG(DFATAL) << "This should be fatal in debug mode";
+    }, "This should be fatal in debug mode");
+#endif
+}
+
+#ifdef HAVE_STACKTRACE
+
+static void BacktraceAtHelper() {
+  LOG(INFO) << "Not me";
+
+// The vertical spacing of the next 3 lines is significant.
+  LOG(INFO) << "Backtrace me";
+}
+static int kBacktraceAtLine = __LINE__ - 2;  // The line of the LOG(INFO) above
+
+TEST(LogBacktraceAt, DoesNotBacktraceWhenDisabled) {
+  StrictMock<ScopedMockLog> log;
+
+  FLAGS_log_backtrace_at = "";
+
+  EXPECT_CALL(log, Log(_, _, "Backtrace me"));
+  EXPECT_CALL(log, Log(_, _, "Not me"));
+
+  BacktraceAtHelper();
+}
+
+TEST(LogBacktraceAt, DoesBacktraceAtRightLineWhenEnabled) {
+  StrictMock<ScopedMockLog> log;
+
+  char where[100];
+  snprintf(where, 100, "%s:%d", const_basename(__FILE__), kBacktraceAtLine);
+  FLAGS_log_backtrace_at = where;
+
+  // The LOG at the specified line should include a stacktrace which includes
+  // the name of the containing function, followed by the log message.
+  // We use HasSubstr()s instead of ContainsRegex() for environments
+  // which don't have regexp.
+  EXPECT_CALL(log, Log(_, _, AllOf(HasSubstr("stacktrace:"),
+                                   HasSubstr("BacktraceAtHelper"),
+                                   HasSubstr("main"),
+                                   HasSubstr("Backtrace me"))));
+  // Other LOGs should not include a backtrace.
+  EXPECT_CALL(log, Log(_, _, "Not me"));
+
+  BacktraceAtHelper();
+}
+
+#endif // HAVE_STACKTRACE
+
+#endif // HAVE_LIB_GMOCK
+
+struct UserDefinedClass {
+  bool operator==(const UserDefinedClass&) const { return true; }
+};
+
+inline ostream& operator<<(ostream& out, const UserDefinedClass&) {
+  out << "OK";
+  return out;
+}
+
+TEST(UserDefinedClass, logging) {
+  UserDefinedClass u;
+  vector<string> buf;
+  LOG_STRING(INFO, &buf) << u;
+  CHECK_EQ(1UL, buf.size());
+  CHECK(buf[0].find("OK") != string::npos);
+
+  // We must be able to compile this.
+  CHECK_EQ(u, u);
+}
diff --git a/third_party/google-glog/src/logging_unittest.err b/third_party/google-glog/src/logging_unittest.err
new file mode 100644
index 0000000..2ecc1b0
--- /dev/null
+++ b/third_party/google-glog/src/logging_unittest.err
@@ -0,0 +1,307 @@
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+WARNING: Logging before InitGoogleLogging() is written to STDERR
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] foo bar 10 3.4
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 1: __SUCCESS__ [0]
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 1
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 1
+WDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 1
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 2
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 3: __ENOENT__ [2]
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 3
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log if less than 3 every 2, iteration 3
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 4
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 4
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 5: __EINTR__ [4]
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 5
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 5
+WDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 5, iteration 6
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 6
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 7: __ENXIO__ [6]
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 7
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 7
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 8
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Plog every 2, iteration 9: __ENOEXEC__ [8]
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 4, iteration 9
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 9
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Log every 3, iteration 10
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Log if every 1, iteration 10
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if this
+IDATE TIME__ THREADID logging_unittest.cc:LINE] array
+IDATE TIME__ THREADID logging_unittest.cc:LINE] const array
+EDATE TIME__ THREADID logging_unittest.cc:LINE] foo 1000 0000001000 3e8
+EDATE TIME__ THREADID logging_unittest.cc:LINE] inner
+EDATE TIME__ THREADID logging_unittest.cc:LINE] outer
+no prefix
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo bar 10 3.400000
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: array
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: const array
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __PTRTEST__
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: ptr __NULLP__
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000 0000001000 3e8
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo 1000
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long!
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: RAW_LOG ERROR: The Message was too long!
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0 on
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1 on
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 2 on
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=0 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=0 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=-1 stderrthreshold=0 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=1 logtostderr=0 alsologtostderr=0
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=2 logtostderr=0 alsologtostderr=0
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=1 alsologtostderr=0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=0 stderrthreshold=3 logtostderr=0 alsologtostderr=1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=1 logtostderr=0 alsologtostderr=0
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Test: v=1 stderrthreshold=3 logtostderr=0 alsologtostderr=1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: vlog 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if -1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] log_if info every 1 expr
+EDATE TIME__ THREADID logging_unittest.cc:LINE] log_if error every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] vlog_if 0 every 1 expr
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_STRING: reported error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected info
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected warning
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_STRING:  LOG_STRING: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: reported error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_SINK:
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_SINK_BUT_NOT_TO_LOGFILE: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected info
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected warning
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Captured by LOG_TO_STRING:  LOG_TO_STRING: collected error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported info
+WDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported warning
+EDATE TIME__ THREADID logging_unittest.cc:LINE] LOG_TO_STRING: reported error
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
+EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
+WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffering
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Buffered
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waiting
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Sink got a messages
+IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: Waited
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink is sending out a message: WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Have 0 left
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: IDATE TIME__ THREADID logging_unittest.cc:LINE] Message 1
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: EDATE TIME__ THREADID logging_unittest.cc:LINE] Message 2
+IDATE TIME__ THREADID logging_unittest.cc:LINE] Sink capture: WDATE TIME__ THREADID logging_unittest.cc:LINE] Message 3
diff --git a/third_party/google-glog/src/mock-log.h b/third_party/google-glog/src/mock-log.h
new file mode 100644
index 0000000..30a0f74
--- /dev/null
+++ b/third_party/google-glog/src/mock-log.h
@@ -0,0 +1,156 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Zhanyong Wan
+//
+// Defines the ScopedMockLog class (using Google C++ Mocking
+// Framework), which is convenient for testing code that uses LOG().
+
+#ifndef GLOG_SRC_MOCK_LOG_H_
+#define GLOG_SRC_MOCK_LOG_H_
+
+// For GOOGLE_NAMESPACE. This must go first so we get _XOPEN_SOURCE.
+#include "utilities.h"
+
+#include <string>
+
+#include <gmock/gmock.h>
+
+#include "glog/logging.h"
+
+_START_GOOGLE_NAMESPACE_
+namespace glog_testing {
+
+// A ScopedMockLog object intercepts LOG() messages issued during its
+// lifespan.  Using this together with Google C++ Mocking Framework,
+// it's very easy to test how a piece of code calls LOG().  The
+// typical usage:
+//
+//   TEST(FooTest, LogsCorrectly) {
+//     ScopedMockLog log;
+//
+//     // We expect the WARNING "Something bad!" exactly twice.
+//     EXPECT_CALL(log, Log(WARNING, _, "Something bad!"))
+//         .Times(2);
+//
+//     // We allow foo.cc to call LOG(INFO) any number of times.
+//     EXPECT_CALL(log, Log(INFO, HasSubstr("/foo.cc"), _))
+//         .Times(AnyNumber());
+//
+//     Foo();  // Exercises the code under test.
+//   }
+class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
+ public:
+  // When a ScopedMockLog object is constructed, it starts to
+  // intercept logs.
+  ScopedMockLog() { AddLogSink(this); }
+
+  // When the object is destructed, it stops intercepting logs.
+  virtual ~ScopedMockLog() { RemoveLogSink(this); }
+
+  // Implements the mock method:
+  //
+  //   void Log(LogSeverity severity, const string& file_path,
+  //            const string& message);
+  //
+  // The second argument to Send() is the full path of the source file
+  // in which the LOG() was issued.
+  //
+  // Note, that in a multi-threaded environment, all LOG() messages from a
+  // single thread will be handled in sequence, but that cannot be guaranteed
+  // for messages from different threads. In fact, if the same or multiple
+  // expectations are matched on two threads concurrently, their actions will
+  // be executed concurrently as well and may interleave.
+  MOCK_METHOD3(Log, void(GOOGLE_NAMESPACE::LogSeverity severity,
+                         const std::string& file_path,
+                         const std::string& message));
+
+ private:
+  // Implements the send() virtual function in class LogSink.
+  // Whenever a LOG() statement is executed, this function will be
+  // invoked with information presented in the LOG().
+  //
+  // The method argument list is long and carries much information a
+  // test usually doesn't care about, so we trim the list before
+  // forwarding the call to Log(), which is much easier to use in
+  // tests.
+  //
+  // We still cannot call Log() directly, as it may invoke other LOG()
+  // messages, either due to Invoke, or due to an error logged in
+  // Google C++ Mocking Framework code, which would trigger a deadlock
+  // since a lock is held during send().
+  //
+  // Hence, we save the message for WaitTillSent() which will be called after
+  // the lock on send() is released, and we'll call Log() inside
+  // WaitTillSent(). Since while a single send() call may be running at a
+  // time, multiple WaitTillSent() calls (along with the one send() call) may
+  // be running simultaneously, we ensure thread-safety of the exchange between
+  // send() and WaitTillSent(), and that for each message, LOG(), send(),
+  // WaitTillSent() and Log() are executed in the same thread.
+  virtual void send(GOOGLE_NAMESPACE::LogSeverity severity,
+                    const char* full_filename,
+                    const char* /*base_filename*/, int /*line*/,
+                    const tm* /*tm_time*/,
+                    const char* message, size_t message_len) {
+    // We are only interested in the log severity, full file name, and
+    // log message.
+    message_info_.severity = severity;
+    message_info_.file_path = full_filename;
+    message_info_.message = std::string(message, message_len);
+  }
+
+  // Implements the WaitTillSent() virtual function in class LogSink.
+  // It will be executed after send() and after the global logging lock is
+  // released, so calls within it (or rather within the Log() method called
+  // within) may also issue LOG() statements.
+  //
+  // LOG(), send(), WaitTillSent() and Log() will occur in the same thread for
+  // a given log message.
+  virtual void WaitTillSent() {
+    // First, and very importantly, we save a copy of the message being
+    // processed before calling Log(), since Log() may indirectly call send()
+    // and WaitTillSent() in the same thread again.
+    MessageInfo message_info = message_info_;
+    Log(message_info.severity, message_info.file_path, message_info.message);
+  }
+
+  // All relevant information about a logged message that needs to be passed
+  // from send() to WaitTillSent().
+  struct MessageInfo {
+    GOOGLE_NAMESPACE::LogSeverity severity;
+    std::string file_path;
+    std::string message;
+  };
+  MessageInfo message_info_;
+};
+
+}  // namespace glog_testing
+_END_GOOGLE_NAMESPACE_
+
+#endif  // GLOG_SRC_MOCK_LOG_H_
diff --git a/third_party/google-glog/src/mock-log_test.cc b/third_party/google-glog/src/mock-log_test.cc
new file mode 100644
index 0000000..7d58a30
--- /dev/null
+++ b/third_party/google-glog/src/mock-log_test.cc
@@ -0,0 +1,106 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Zhanyong Wan
+
+// Tests the ScopedMockLog class.
+
+#include "mock-log.h"
+
+#include <string>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace {
+
+using GOOGLE_NAMESPACE::INFO;
+using GOOGLE_NAMESPACE::WARNING;
+using GOOGLE_NAMESPACE::ERROR;
+using GOOGLE_NAMESPACE::glog_testing::ScopedMockLog;
+using std::string;
+using testing::_;
+using testing::HasSubstr;
+using testing::InSequence;
+using testing::InvokeWithoutArgs;
+
+// Tests that ScopedMockLog intercepts LOG()s when it's alive.
+TEST(ScopedMockLogTest, InterceptsLog) {
+  ScopedMockLog log;
+
+  InSequence s;
+  EXPECT_CALL(log, Log(WARNING, HasSubstr("/mock-log_test.cc"), "Fishy."));
+  EXPECT_CALL(log, Log(INFO, _, "Working..."))
+      .Times(2);
+  EXPECT_CALL(log, Log(ERROR, _, "Bad!!"));
+
+  LOG(WARNING) << "Fishy.";
+  LOG(INFO) << "Working...";
+  LOG(INFO) << "Working...";
+  LOG(ERROR) << "Bad!!";
+}
+
+void LogBranch() {
+  LOG(INFO) << "Logging a branch...";
+}
+
+void LogTree() {
+  LOG(INFO) << "Logging the whole tree...";
+}
+
+void LogForest() {
+  LOG(INFO) << "Logging the entire forest.";
+  LOG(INFO) << "Logging the entire forest..";
+  LOG(INFO) << "Logging the entire forest...";
+}
+
+// The purpose of the following test is to verify that intercepting logging
+// continues to work properly if a LOG statement is executed within the scope
+// of a mocked call.
+TEST(ScopedMockLogTest, LogDuringIntercept) {
+  ScopedMockLog log;
+  InSequence s;
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging a branch..."))
+      .WillOnce(InvokeWithoutArgs(LogTree));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the whole tree..."))
+      .WillOnce(InvokeWithoutArgs(LogForest));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest."));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest.."));
+  EXPECT_CALL(log, Log(INFO, __FILE__, "Logging the entire forest..."));
+  LogBranch();
+}
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  GOOGLE_NAMESPACE::InitGoogleLogging(argv[0]);
+  testing::InitGoogleMock(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/third_party/google-glog/src/raw_logging.cc b/third_party/google-glog/src/raw_logging.cc
new file mode 100644
index 0000000..7a7409b
--- /dev/null
+++ b/third_party/google-glog/src/raw_logging.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Maxim Lifantsev
+//
+// logging_unittest.cc covers the functionality herein
+
+#include "utilities.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>               // for close() and write()
+#endif
+#include <fcntl.h>                 // for open()
+#include <time.h>
+#include "config.h"
+#include "glog/logging.h"          // To pick up flag settings etc.
+#include "glog/raw_logging.h"
+#include "base/commandlineflags.h"
+
+#ifdef HAVE_STACKTRACE
+# include "stacktrace.h"
+#endif
+
+#if defined(HAVE_SYSCALL_H)
+#include <syscall.h>                 // for syscall()
+#elif defined(HAVE_SYS_SYSCALL_H)
+#include <sys/syscall.h>                 // for syscall()
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H)
+# define safe_write(fd, s, len)  syscall(SYS_write, fd, s, len)
+#else
+  // Not so safe, but what can you do?
+# define safe_write(fd, s, len)  write(fd, s, len)
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+// Data for RawLog__ below. We simply pick up the latest
+// time data created by a normal log message to avoid calling
+// localtime_r which can allocate memory.
+static struct ::tm last_tm_time_for_raw_log;
+static int last_usecs_for_raw_log;
+
+void RawLog__SetLastTime(const struct ::tm& t, int usecs) {
+  memcpy(&last_tm_time_for_raw_log, &t, sizeof(last_tm_time_for_raw_log));
+  last_usecs_for_raw_log = usecs;
+}
+
+// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths
+// that invoke malloc() and getenv() that might acquire some locks.
+// If this becomes a problem we should reimplement a subset of vsnprintf
+// that does not need locks and malloc.
+
+// Helper for RawLog__ below.
+// *DoRawLog writes to *buf of *size and move them past the written portion.
+// It returns true iff there was no overflow or error.
+static bool DoRawLog(char** buf, int* size, const char* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  int n = vsnprintf(*buf, *size, format, ap);
+  va_end(ap);
+  if (n < 0 || n > *size) return false;
+  *size -= n;
+  *buf += n;
+  return true;
+}
+
+// Helper for RawLog__ below.
+inline static bool VADoRawLog(char** buf, int* size,
+                              const char* format, va_list ap) {
+  int n = vsnprintf(*buf, *size, format, ap);
+  if (n < 0 || n > *size) return false;
+  *size -= n;
+  *buf += n;
+  return true;
+}
+
+static const int kLogBufSize = 3000;
+static bool crashed = false;
+static CrashReason crash_reason;
+static char crash_buf[kLogBufSize + 1] = { 0 };  // Will end in '\0'
+
+void RawLog__(LogSeverity severity, const char* file, int line,
+              const char* format, ...) {
+  if (!(FLAGS_logtostderr || severity >= FLAGS_stderrthreshold ||
+        FLAGS_alsologtostderr || !IsGoogleLoggingInitialized())) {
+    return;  // this stderr log message is suppressed
+  }
+  // can't call localtime_r here: it can allocate
+  struct ::tm& t = last_tm_time_for_raw_log;
+  char buffer[kLogBufSize];
+  char* buf = buffer;
+  int size = sizeof(buffer);
+
+  // NOTE: this format should match the specification in base/logging.h
+  DoRawLog(&buf, &size, "%c%02d%02d %02d:%02d:%02d.%06d %5u %s:%d] RAW: ",
+           LogSeverityNames[severity][0],
+           1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
+           last_usecs_for_raw_log,
+           static_cast<unsigned int>(GetTID()),
+           const_basename(const_cast<char *>(file)), line);
+
+  // Record the position and size of the buffer after the prefix
+  const char* msg_start = buf;
+  const int msg_size = size;
+
+  va_list ap;
+  va_start(ap, format);
+  bool no_chop = VADoRawLog(&buf, &size, format, ap);
+  va_end(ap);
+  if (no_chop) {
+    DoRawLog(&buf, &size, "\n");
+  } else {
+    DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n");
+  }
+  // We make a raw syscall to write directly to the stderr file descriptor,
+  // avoiding FILE buffering (to avoid invoking malloc()), and bypassing
+  // libc (to side-step any libc interception).
+  // We write just once to avoid races with other invocations of RawLog__.
+  safe_write(STDERR_FILENO, buffer, strlen(buffer));
+  if (severity == GLOG_FATAL)  {
+    if (!sync_val_compare_and_swap(&crashed, false, true)) {
+      crash_reason.filename = file;
+      crash_reason.line_number = line;
+      memcpy(crash_buf, msg_start, msg_size);  // Don't include prefix
+      crash_reason.message = crash_buf;
+#ifdef HAVE_STACKTRACE
+      crash_reason.depth =
+          GetStackTrace(crash_reason.stack, ARRAYSIZE(crash_reason.stack), 1);
+#else
+      crash_reason.depth = 0;
+#endif
+      SetCrashReason(&crash_reason);
+    }
+    LogMessage::Fail();  // abort()
+  }
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/signalhandler.cc b/third_party/google-glog/src/signalhandler.cc
new file mode 100644
index 0000000..c3a0f80
--- /dev/null
+++ b/third_party/google-glog/src/signalhandler.cc
@@ -0,0 +1,411 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// Implementation of InstallFailureSignalHandler().
+
+#include "utilities.h"
+#include "stacktrace.h"
+#include "symbolize.h"
+#include "glog/logging.h"
+
+#include <signal.h>
+#include <time.h>
+#ifdef HAVE_UCONTEXT_H
+# include <ucontext.h>
+#endif
+#ifdef HAVE_SYS_UCONTEXT_H
+# include <sys/ucontext.h>
+#endif
+#include <algorithm>
+
+_START_GOOGLE_NAMESPACE_
+
+namespace {
+
+// We'll install the failure signal handler for these signals.  We could
+// use strsignal() to get signal names, but we don't use it to avoid
+// introducing yet another #ifdef complication.
+//
+// The list should be synced with the comment in signalhandler.h.
+const struct {
+  int number;
+  const char *name;
+} kFailureSignals[] = {
+  { SIGSEGV, "SIGSEGV" },
+  { SIGILL, "SIGILL" },
+  { SIGFPE, "SIGFPE" },
+  { SIGABRT, "SIGABRT" },
+#if !defined(OS_WINDOWS)
+  { SIGBUS, "SIGBUS" },
+#endif
+  { SIGTERM, "SIGTERM" },
+};
+
+static bool kFailureSignalHandlerInstalled = false;
+
+// Returns the program counter from signal context, NULL if unknown.
+void* GetPC(void* ucontext_in_void) {
+#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
+  if (ucontext_in_void != NULL) {
+    ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void);
+    return (void*)context->PC_FROM_UCONTEXT;
+  }
+#else
+  (void)ucontext_in_void;
+#endif
+  return NULL;
+}
+
+// The class is used for formatting error messages.  We don't use printf()
+// as it's not async signal safe.
+class MinimalFormatter {
+ public:
+  MinimalFormatter(char *buffer, int size)
+      : buffer_(buffer),
+        cursor_(buffer),
+        end_(buffer + size) {
+  }
+
+  // Returns the number of bytes written in the buffer.
+  int num_bytes_written() const { return (int) (cursor_ - buffer_); }
+
+  // Appends string from "str" and updates the internal cursor.
+  void AppendString(const char* str) {
+    int i = 0;
+    while (str[i] != '\0' && cursor_ + i < end_) {
+      cursor_[i] = str[i];
+      ++i;
+    }
+    cursor_ += i;
+  }
+
+  // Formats "number" in "radix" and updates the internal cursor.
+  // Lowercase letters are used for 'a' - 'z'.
+  void AppendUint64(uint64 number, int radix) {
+    int i = 0;
+    while (cursor_ + i < end_) {
+      const int tmp = number % radix;
+      number /= radix;
+      cursor_[i] = (tmp < 10 ? '0' + tmp : 'a' + tmp - 10);
+      ++i;
+      if (number == 0) {
+        break;
+      }
+    }
+    // Reverse the bytes written.
+    std::reverse(cursor_, cursor_ + i);
+    cursor_ += i;
+  }
+
+  // Formats "number" as hexadecimal number, and updates the internal
+  // cursor.  Padding will be added in front if needed.
+  void AppendHexWithPadding(uint64 number, int width) {
+    char* start = cursor_;
+    AppendString("0x");
+    AppendUint64(number, 16);
+    // Move to right and add padding in front if needed.
+    if (cursor_ < start + width) {
+      const int64 delta = start + width - cursor_;
+      std::copy(start, cursor_, start + delta);
+      std::fill(start, start + delta, ' ');
+      cursor_ = start + width;
+    }
+  }
+
+ private:
+  char *buffer_;
+  char *cursor_;
+  const char * const end_;
+};
+
+// Writes the given data with the size to the standard error.
+void WriteToStderr(const char* data, int size) {
+  if (write(STDERR_FILENO, data, size) < 0) {
+    // Ignore errors.
+  }
+}
+
+// The writer function can be changed by InstallFailureWriter().
+void (*g_failure_writer)(const char* data, int size) = WriteToStderr;
+
+// Dumps time information.  We don't dump human-readable time information
+// as localtime() is not guaranteed to be async signal safe.
+void DumpTimeInfo() {
+  time_t time_in_sec = time(NULL);
+  char buf[256];  // Big enough for time info.
+  MinimalFormatter formatter(buf, sizeof(buf));
+  formatter.AppendString("*** Aborted at ");
+  formatter.AppendUint64(time_in_sec, 10);
+  formatter.AppendString(" (unix time)");
+  formatter.AppendString(" try \"date -d @");
+  formatter.AppendUint64(time_in_sec, 10);
+  formatter.AppendString("\" if you are using GNU date ***\n");
+  g_failure_writer(buf, formatter.num_bytes_written());
+}
+
+// TOOD(hamaji): Use signal instead of sigaction?
+#ifdef HAVE_SIGACTION
+
+// Dumps information about the signal to STDERR.
+void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
+  // Get the signal name.
+  const char* signal_name = NULL;
+  for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
+    if (signal_number == kFailureSignals[i].number) {
+      signal_name = kFailureSignals[i].name;
+    }
+  }
+
+  char buf[256];  // Big enough for signal info.
+  MinimalFormatter formatter(buf, sizeof(buf));
+
+  formatter.AppendString("*** ");
+  if (signal_name) {
+    formatter.AppendString(signal_name);
+  } else {
+    // Use the signal number if the name is unknown.  The signal name
+    // should be known, but just in case.
+    formatter.AppendString("Signal ");
+    formatter.AppendUint64(signal_number, 10);
+  }
+  formatter.AppendString(" (@0x");
+  formatter.AppendUint64(reinterpret_cast<uintptr_t>(siginfo->si_addr), 16);
+  formatter.AppendString(")");
+  formatter.AppendString(" received by PID ");
+  formatter.AppendUint64(getpid(), 10);
+  formatter.AppendString(" (TID 0x");
+  // We assume pthread_t is an integral number or a pointer, rather
+  // than a complex struct.  In some environments, pthread_self()
+  // returns an uint64 but in some other environments pthread_self()
+  // returns a pointer.  Hence we use C-style cast here, rather than
+  // reinterpret/static_cast, to support both types of environments.
+  formatter.AppendUint64((uintptr_t)pthread_self(), 16);
+  formatter.AppendString(") ");
+  // Only linux has the PID of the signal sender in si_pid.
+#ifdef OS_LINUX
+  formatter.AppendString("from PID ");
+  formatter.AppendUint64(siginfo->si_pid, 10);
+  formatter.AppendString("; ");
+#endif
+  formatter.AppendString("stack trace: ***\n");
+  g_failure_writer(buf, formatter.num_bytes_written());
+}
+
+#endif  // HAVE_SIGACTION
+
+// Dumps information about the stack frame to STDERR.
+void DumpStackFrameInfo(const char* prefix, void* pc) {
+  // Get the symbol name.
+  const char *symbol = "(unknown)";
+  char symbolized[1024];  // Big enough for a sane symbol.
+  // Symbolizes the previous address of pc because pc may be in the
+  // next function.
+  if (Symbolize(reinterpret_cast<char *>(pc) - 1,
+                symbolized, sizeof(symbolized))) {
+    symbol = symbolized;
+  }
+
+  char buf[1024];  // Big enough for stack frame info.
+  MinimalFormatter formatter(buf, sizeof(buf));
+
+  formatter.AppendString(prefix);
+  formatter.AppendString("@ ");
+  const int width = 2 * sizeof(void*) + 2;  // + 2  for "0x".
+  formatter.AppendHexWithPadding(reinterpret_cast<uintptr_t>(pc), width);
+  formatter.AppendString(" ");
+  formatter.AppendString(symbol);
+  formatter.AppendString("\n");
+  g_failure_writer(buf, formatter.num_bytes_written());
+}
+
+// Invoke the default signal handler.
+void InvokeDefaultSignalHandler(int signal_number) {
+#ifdef HAVE_SIGACTION
+  struct sigaction sig_action;
+  memset(&sig_action, 0, sizeof(sig_action));
+  sigemptyset(&sig_action.sa_mask);
+  sig_action.sa_handler = SIG_DFL;
+  sigaction(signal_number, &sig_action, NULL);
+  kill(getpid(), signal_number);
+#elif defined(OS_WINDOWS)
+  signal(signal_number, SIG_DFL);
+  raise(signal_number);
+#endif
+}
+
+// This variable is used for protecting FailureSignalHandler() from
+// dumping stuff while another thread is doing it.  Our policy is to let
+// the first thread dump stuff and let other threads wait.
+// See also comments in FailureSignalHandler().
+static pthread_t* g_entered_thread_id_pointer = NULL;
+
+// Dumps signal and stack frame information, and invokes the default
+// signal handler once our job is done.
+#if defined(OS_WINDOWS)
+void FailureSignalHandler(int signal_number)
+#else
+void FailureSignalHandler(int signal_number,
+                          siginfo_t *signal_info,
+                          void *ucontext)
+#endif
+{
+  // First check if we've already entered the function.  We use an atomic
+  // compare and swap operation for platforms that support it.  For other
+  // platforms, we use a naive method that could lead to a subtle race.
+
+  // We assume pthread_self() is async signal safe, though it's not
+  // officially guaranteed.
+  pthread_t my_thread_id = pthread_self();
+  // NOTE: We could simply use pthread_t rather than pthread_t* for this,
+  // if pthread_self() is guaranteed to return non-zero value for thread
+  // ids, but there is no such guarantee.  We need to distinguish if the
+  // old value (value returned from __sync_val_compare_and_swap) is
+  // different from the original value (in this case NULL).
+  pthread_t* old_thread_id_pointer =
+      glog_internal_namespace_::sync_val_compare_and_swap(
+          &g_entered_thread_id_pointer,
+          static_cast<pthread_t*>(NULL),
+          &my_thread_id);
+  if (old_thread_id_pointer != NULL) {
+    // We've already entered the signal handler.  What should we do?
+    if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
+      // It looks the current thread is reentering the signal handler.
+      // Something must be going wrong (maybe we are reentering by another
+      // type of signal?).  Kill ourself by the default signal handler.
+      InvokeDefaultSignalHandler(signal_number);
+    }
+    // Another thread is dumping stuff.  Let's wait until that thread
+    // finishes the job and kills the process.
+    while (true) {
+      sleep(1);
+    }
+  }
+  // This is the first time we enter the signal handler.  We are going to
+  // do some interesting stuff from here.
+  // TODO(satorux): We might want to set timeout here using alarm(), but
+  // mixing alarm() and sleep() can be a bad idea.
+
+  // First dump time info.
+  DumpTimeInfo();
+
+#if !defined(OS_WINDOWS)
+  // Get the program counter from ucontext.
+  void *pc = GetPC(ucontext);
+  DumpStackFrameInfo("PC: ", pc);
+#else
+  (void)ucontext;
+#endif
+
+#ifdef HAVE_STACKTRACE
+  // Get the stack traces.
+  void *stack[32];
+  // +1 to exclude this function.
+  const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1);
+# ifdef HAVE_SIGACTION
+  DumpSignalInfo(signal_number, signal_info);
+# else
+  (void)signal_info;
+# endif
+  // Dump the stack traces.
+  for (int i = 0; i < depth; ++i) {
+    DumpStackFrameInfo("    ", stack[i]);
+  }
+#else
+  (void)signal_info;
+#endif
+
+  // *** TRANSITION ***
+  //
+  // BEFORE this point, all code must be async-termination-safe!
+  // (See WARNING above.)
+  //
+  // AFTER this point, we do unsafe things, like using LOG()!
+  // The process could be terminated or hung at any time.  We try to
+  // do more useful things first and riskier things later.
+
+  // Flush the logs before we do anything in case 'anything'
+  // causes problems.
+  FlushLogFilesUnsafe(0);
+
+  // Kill ourself by the default signal handler.
+  InvokeDefaultSignalHandler(signal_number);
+}
+
+}  // namespace
+
+namespace glog_internal_namespace_ {
+
+bool IsFailureSignalHandlerInstalled() {
+#ifdef HAVE_SIGACTION
+  // TODO(andschwa): Return kFailureSignalHandlerInstalled?
+  struct sigaction sig_action;
+  memset(&sig_action, 0, sizeof(sig_action));
+  sigemptyset(&sig_action.sa_mask);
+  sigaction(SIGABRT, NULL, &sig_action);
+  if (sig_action.sa_sigaction == &FailureSignalHandler)
+    return true;
+#elif defined(OS_WINDOWS)
+  return kFailureSignalHandlerInstalled;
+#endif  // HAVE_SIGACTION
+  return false;
+}
+
+}  // namespace glog_internal_namespace_
+
+void InstallFailureSignalHandler() {
+#ifdef HAVE_SIGACTION
+  // Build the sigaction struct.
+  struct sigaction sig_action;
+  memset(&sig_action, 0, sizeof(sig_action));
+  sigemptyset(&sig_action.sa_mask);
+  sig_action.sa_flags |= SA_SIGINFO;
+  sig_action.sa_sigaction = &FailureSignalHandler;
+
+  for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
+    CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL));
+  }
+  kFailureSignalHandlerInstalled = true;
+#elif defined(OS_WINDOWS)
+  for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) {
+    CHECK_NE(signal(kFailureSignals[i].number, &FailureSignalHandler),
+             SIG_ERR);
+  }
+  kFailureSignalHandlerInstalled = true;
+#endif  // HAVE_SIGACTION
+}
+
+void InstallFailureWriter(void (*writer)(const char* data, int size)) {
+#if defined(HAVE_SIGACTION) || defined(OS_WINDOWS)
+  g_failure_writer = writer;
+#endif  // HAVE_SIGACTION
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/signalhandler_unittest.cc b/third_party/google-glog/src/signalhandler_unittest.cc
new file mode 100644
index 0000000..36d957b
--- /dev/null
+++ b/third_party/google-glog/src/signalhandler_unittest.cc
@@ -0,0 +1,112 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// This is a helper binary for testing signalhandler.cc.  The actual test
+// is done in signalhandler_unittest.sh.
+
+#include "utilities.h"
+
+#if defined(HAVE_PTHREAD)
+# include <pthread.h>
+#endif
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include "glog/logging.h"
+
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+using namespace GFLAGS_NAMESPACE;
+#endif
+
+using namespace GOOGLE_NAMESPACE;
+
+static void* DieInThread(void*) {
+  // We assume pthread_t is an integral number or a pointer, rather
+  // than a complex struct.  In some environments, pthread_self()
+  // returns an uint64 but in some other environments pthread_self()
+  // returns a pointer.  Hence we use C-style cast here, rather than
+  // reinterpret/static_cast, to support both types of environments.
+  fprintf(stderr, "0x%lx is dying\n", (long)pthread_self());
+  // Use volatile to prevent from these to be optimized away.
+  volatile int a = 0;
+  volatile int b = 1 / a;
+  fprintf(stderr, "We should have died: b=%d\n", b);
+  return NULL;
+}
+
+static void WriteToStdout(const char* data, int size) {
+  if (write(STDOUT_FILENO, data, size) < 0) {
+    // Ignore errors.
+  }
+}
+
+int main(int argc, char **argv) {
+#if defined(HAVE_STACKTRACE) && defined(HAVE_SYMBOLIZE)
+  InitGoogleLogging(argv[0]);
+#ifdef HAVE_LIB_GFLAGS
+  ParseCommandLineFlags(&argc, &argv, true);
+#endif
+  InstallFailureSignalHandler();
+  const std::string command = argc > 1 ? argv[1] : "none";
+  if (command == "segv") {
+    // We'll check if this is outputted.
+    LOG(INFO) << "create the log file";
+    LOG(INFO) << "a message before segv";
+    // We assume 0xDEAD is not writable.
+    int *a = (int*)0xDEAD;
+    *a = 0;
+  } else if (command == "loop") {
+    fprintf(stderr, "looping\n");
+    while (true);
+  } else if (command == "die_in_thread") {
+#if defined(HAVE_PTHREAD)
+    pthread_t thread;
+    pthread_create(&thread, NULL, &DieInThread, NULL);
+    pthread_join(thread, NULL);
+#else
+    fprintf(stderr, "no pthread\n");
+    return 1;
+#endif
+  } else if (command == "dump_to_stdout") {
+    InstallFailureWriter(WriteToStdout);
+    abort();
+  } else if (command == "installed") {
+    fprintf(stderr, "signal handler installed: %s\n",
+        IsFailureSignalHandlerInstalled() ? "true" : "false");
+  } else {
+    // Tell the shell script
+    puts("OK");
+  }
+#endif
+  return 0;
+}
diff --git a/third_party/google-glog/src/signalhandler_unittest.sh b/third_party/google-glog/src/signalhandler_unittest.sh
new file mode 100755
index 0000000..265cd45
--- /dev/null
+++ b/third_party/google-glog/src/signalhandler_unittest.sh
@@ -0,0 +1,131 @@
+#! /bin/sh
+#
+# Copyright (c) 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: Satoru Takabayashi
+#
+# Unit tests for signalhandler.cc.
+
+die () {
+    echo $1
+    exit 1
+}
+
+BINDIR=".libs"
+LIBGLOG="$BINDIR/libglog.so"
+
+BINARY="$BINDIR/signalhandler_unittest"
+LOG_INFO="./signalhandler_unittest.INFO"
+
+# Remove temporary files.
+rm -f signalhandler.out*
+
+if test -e "$BINARY"; then
+  # We need shared object.
+  export LD_LIBRARY_PATH=$BINDIR
+  export DYLD_LIBRARY_PATH=$BINDIR
+else
+  # For windows
+  BINARY="./signalhandler_unittest.exe"
+  if ! test -e "$BINARY"; then
+    echo "We coundn't find demangle_unittest binary."
+    exit 1
+  fi
+fi
+
+if [ x`$BINARY` != 'xOK' ]; then
+  echo "PASS (No stacktrace support. We don't run this test.)"
+  exit 0
+fi
+
+# The PC cannot be obtained in signal handlers on PowerPC correctly.
+# We just skip the test for PowerPC.
+if [ x`uname -p` = x"powerpc" ]; then
+  echo "PASS (We don't test the signal handler on PowerPC.)"
+  exit 0
+fi
+
+# Test for a case the program kills itself by SIGSEGV.
+GOOGLE_LOG_DIR=. $BINARY segv 2> signalhandler.out1
+for pattern in SIGSEGV 0xdead main "Aborted at [0-9]"; do
+  if ! grep --quiet "$pattern" signalhandler.out1; then
+    die "'$pattern' should appear in the output"
+  fi
+done
+if ! grep --quiet "a message before segv" $LOG_INFO; then
+  die "'a message before segv' should appear in the INFO log"
+fi
+rm -f $LOG_INFO
+
+# Test for a case the program is killed by this shell script.
+# $! = the process id of the last command run in the background.
+# $$ = the process id of this shell.
+$BINARY loop 2> signalhandler.out2 &
+# Wait until "looping" is written in the file.  This indicates the program
+# is ready to accept signals.
+while true; do
+  if grep --quiet looping signalhandler.out2; then
+    break
+  fi
+done
+kill -TERM $!
+wait $!
+
+from_pid=''
+# Only linux has the process ID of the signal sender.
+if [ x`uname` = "xLinux" ]; then
+  from_pid="from PID $$"
+fi
+for pattern in SIGTERM "by PID $!" "$from_pid" main "Aborted at [0-9]"; do
+  if ! grep --quiet "$pattern" signalhandler.out2; then
+    die "'$pattern' should appear in the output"
+  fi
+done
+
+# Test for a case the program dies in a non-main thread.
+$BINARY die_in_thread 2> signalhandler.out3
+EXPECTED_TID="`sed 's/ .*//; q' signalhandler.out3`"
+
+for pattern in SIGFPE DieInThread "TID $EXPECTED_TID" "Aborted at [0-9]"; do
+  if ! grep --quiet "$pattern" signalhandler.out3; then
+    die "'$pattern' should appear in the output"
+  fi
+done
+
+# Test for a case the program installs a custom failure writer that writes
+# stuff to stdout instead of stderr.
+$BINARY dump_to_stdout 1> signalhandler.out4
+for pattern in SIGABRT main "Aborted at [0-9]"; do
+  if ! grep --quiet "$pattern" signalhandler.out4; then
+    die "'$pattern' should appear in the output"
+  fi
+done
+
+echo PASS
diff --git a/third_party/google-glog/src/stacktrace.h b/third_party/google-glog/src/stacktrace.h
new file mode 100644
index 0000000..cb64b33
--- /dev/null
+++ b/third_party/google-glog/src/stacktrace.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2000 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Routines to extract the current stack trace.  These functions are
+// thread-safe.
+
+#ifndef BASE_STACKTRACE_H_
+#define BASE_STACKTRACE_H_
+
+#include "config.h"
+#include "glog/logging.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// This is similar to the GetStackFrames routine, except that it returns
+// the stack trace only, and not the stack frame sizes as well.
+// Example:
+//      main() { foo(); }
+//      foo() { bar(); }
+//      bar() {
+//        void* result[10];
+//        int depth = GetStackFrames(result, 10, 1);
+//      }
+//
+// This produces:
+//      result[0]       foo
+//      result[1]       main
+//           ....       ...
+//
+// "result" must not be NULL.
+GOOGLE_GLOG_DLL_DECL int GetStackTrace(void** result, int max_depth, int skip_count);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif  // BASE_STACKTRACE_H_
diff --git a/third_party/google-glog/src/stacktrace_generic-inl.h b/third_party/google-glog/src/stacktrace_generic-inl.h
new file mode 100644
index 0000000..fad81d3
--- /dev/null
+++ b/third_party/google-glog/src/stacktrace_generic-inl.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2000 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Portable implementation - just use glibc
+//
+// Note:  The glibc implementation may cause a call to malloc.
+// This can cause a deadlock in HeapProfiler.
+#include <execinfo.h>
+#include <string.h>
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+  static const int kStackLength = 64;
+  void * stack[kStackLength];
+  int size;
+
+  size = backtrace(stack, kStackLength);
+  skip_count++;  // we want to skip the current frame as well
+  int result_count = size - skip_count;
+  if (result_count < 0)
+    result_count = 0;
+  if (result_count > max_depth)
+    result_count = max_depth;
+  for (int i = 0; i < result_count; i++)
+    result[i] = stack[i + skip_count];
+
+  return result_count;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_libunwind-inl.h b/third_party/google-glog/src/stacktrace_libunwind-inl.h
new file mode 100644
index 0000000..0dc14c6
--- /dev/null
+++ b/third_party/google-glog/src/stacktrace_libunwind-inl.h
@@ -0,0 +1,87 @@
+// Copyright (c) 2005 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Arun Sharma
+//
+// Produce stack trace using libunwind
+
+#include "utilities.h"
+
+extern "C" {
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+}
+#include "glog/raw_logging.h"
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// Sometimes, we can try to get a stack trace from within a stack
+// trace, because libunwind can call mmap (maybe indirectly via an
+// internal mmap based memory allocator), and that mmap gets trapped
+// and causes a stack-trace request.  If were to try to honor that
+// recursive request, we'd end up with infinite recursion or deadlock.
+// Luckily, it's safe to ignore those subsequent traces.  In such
+// cases, we return 0 to indicate the situation.
+static bool g_now_entering = false;
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+  void *ip;
+  int n = 0;
+  unw_cursor_t cursor;
+  unw_context_t uc;
+
+  if (sync_val_compare_and_swap(&g_now_entering, false, true)) {
+    return 0;
+  }
+
+  unw_getcontext(&uc);
+  RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed");
+  skip_count++;         // Do not include the "GetStackTrace" frame
+
+  while (n < max_depth) {
+    int ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip);
+    if (ret < 0)
+      break;
+    if (skip_count > 0) {
+      skip_count--;
+    } else {
+      result[n++] = ip;
+    }
+    ret = unw_step(&cursor);
+    if (ret <= 0)
+      break;
+  }
+
+  g_now_entering = false;
+  return n;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_powerpc-inl.h b/third_party/google-glog/src/stacktrace_powerpc-inl.h
new file mode 100644
index 0000000..03b9108
--- /dev/null
+++ b/third_party/google-glog/src/stacktrace_powerpc-inl.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Craig Silverstein
+//
+// Produce stack trace.  I'm guessing (hoping!) the code is much like
+// for x86.  For apple machines, at least, it seems to be; see
+//    http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html
+//    http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
+// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882
+
+#include <stdio.h>
+#include <stdint.h>   // for uintptr_t
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// Given a pointer to a stack frame, locate and return the calling
+// stackframe, or return NULL if no stackframe can be found. Perform sanity
+// checks (the strictness of which is controlled by the boolean parameter
+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
+template<bool STRICT_UNWINDING>
+static void **NextStackFrame(void **old_sp) {
+  void **new_sp = (void **) *old_sp;
+
+  // Check that the transition from frame pointer old_sp to frame
+  // pointer new_sp isn't clearly bogus
+  if (STRICT_UNWINDING) {
+    // With the stack growing downwards, older stack frame must be
+    // at a greater address that the current one.
+    if (new_sp <= old_sp) return NULL;
+    // Assume stack frames larger than 100,000 bytes are bogus.
+    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
+  } else {
+    // In the non-strict mode, allow discontiguous stack frames.
+    // (alternate-signal-stacks for example).
+    if (new_sp == old_sp) return NULL;
+    // And allow frames upto about 1MB.
+    if ((new_sp > old_sp)
+        && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
+  }
+  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
+  return new_sp;
+}
+
+// This ensures that GetStackTrace stes up the Link Register properly.
+void StacktracePowerPCDummyFunction() __attribute__((noinline));
+void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+  void **sp;
+  // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther)
+  // and Darwin 8.8.1 (Tiger) use as 1.38.  This means we have to use a
+  // different asm syntax.  I don't know quite the best way to discriminate
+  // systems using the old as from the new one; I've gone with __APPLE__.
+#ifdef __APPLE__
+  __asm__ volatile ("mr %0,r1" : "=r" (sp));
+#else
+  __asm__ volatile ("mr %0,1" : "=r" (sp));
+#endif
+
+  // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack
+  // entry that holds the return address of the subroutine call (what
+  // instruction we run after our function finishes).  This is the
+  // same as the stack-pointer of our parent routine, which is what we
+  // want here.  While the compiler will always(?) set up LR for
+  // subroutine calls, it may not for leaf functions (such as this one).
+  // This routine forces the compiler (at least gcc) to push it anyway.
+  StacktracePowerPCDummyFunction();
+
+  // The LR save area is used by the callee, so the top entry is bogus.
+  skip_count++;
+
+  int n = 0;
+  while (sp && n < max_depth) {
+    if (skip_count > 0) {
+      skip_count--;
+    } else {
+      // PowerPC has 3 main ABIs, which say where in the stack the
+      // Link Register is.  For DARWIN and AIX (used by apple and
+      // linux ppc64), it's in sp[2].  For SYSV (used by linux ppc),
+      // it's in sp[1].
+#if defined(_CALL_AIX) || defined(_CALL_DARWIN)
+      result[n++] = *(sp+2);
+#elif defined(_CALL_SYSV)
+      result[n++] = *(sp+1);
+#elif defined(__APPLE__) || ((defined(__linux) || defined(__linux__)) && defined(__PPC64__))
+      // This check is in case the compiler doesn't define _CALL_AIX/etc.
+      result[n++] = *(sp+2);
+#elif defined(__linux)
+      // This check is in case the compiler doesn't define _CALL_SYSV.
+      result[n++] = *(sp+1);
+#else
+#error Need to specify the PPC ABI for your archiecture.
+#endif
+    }
+    // Use strict unwinding rules.
+    sp = NextStackFrame<true>(sp);
+  }
+  return n;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_unittest.cc b/third_party/google-glog/src/stacktrace_unittest.cc
new file mode 100644
index 0000000..c6ab638
--- /dev/null
+++ b/third_party/google-glog/src/stacktrace_unittest.cc
@@ -0,0 +1,208 @@
+// Copyright (c) 2004, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "utilities.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "config.h"
+#include "base/commandlineflags.h"
+#include "glog/logging.h"
+#include "stacktrace.h"
+
+#ifdef HAVE_EXECINFO_H
+# include <execinfo.h>
+#endif
+
+using namespace GOOGLE_NAMESPACE;
+
+#ifdef HAVE_STACKTRACE
+
+// Obtain a backtrace, verify that the expected callers are present in the
+// backtrace, and maybe print the backtrace to stdout.
+
+// The sequence of functions whose return addresses we expect to see in the
+// backtrace.
+const int BACKTRACE_STEPS = 6;
+
+struct AddressRange {
+  const void *start, *end;
+};
+
+// Expected function [start,end] range.
+AddressRange expected_range[BACKTRACE_STEPS];
+
+#if __GNUC__
+// Using GCC extension: address of a label can be taken with '&&label'.
+// Start should be a label somewhere before recursive call, end somewhere
+// after it.
+#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange)           \
+  do {                                                                   \
+    (prange)->start = &&start_label;                                     \
+    (prange)->end = &&end_label;                                         \
+    CHECK_LT((prange)->start, (prange)->end);                            \
+  } while (0)
+// This macro expands into "unmovable" code (opaque to GCC), and that
+// prevents GCC from moving a_label up or down in the code.
+// Without it, there is no code following the 'end' label, and GCC
+// (4.3.1, 4.4.0) thinks it safe to assign &&end an address that is before
+// the recursive call.
+#define DECLARE_ADDRESS_LABEL(a_label)                                   \
+  a_label: do { __asm__ __volatile__(""); } while (0)
+// Gcc 4.4.0 may split function into multiple chunks, and the chunk
+// performing recursive call may end up later in the code then the return
+// instruction (this actually happens with FDO).
+// Adjust function range from __builtin_return_address.
+#define ADJUST_ADDRESS_RANGE_FROM_RA(prange)                             \
+  do {                                                                   \
+    void *ra = __builtin_return_address(0);                              \
+    CHECK_LT((prange)->start, ra);                                       \
+    if (ra > (prange)->end) {                                            \
+      printf("Adjusting range from %p..%p to %p..%p\n",                  \
+             (prange)->start, (prange)->end,                             \
+             (prange)->start, ra);                                       \
+      (prange)->end = ra;                                                \
+    }                                                                    \
+  } while (0)
+#else
+// Assume the Check* functions below are not longer than 256 bytes.
+#define INIT_ADDRESS_RANGE(fn, start_label, end_label, prange)           \
+  do {                                                                   \
+    (prange)->start = reinterpret_cast<const void *>(&fn);               \
+    (prange)->end = reinterpret_cast<const char *>(&fn) + 256;           \
+  } while (0)
+#define DECLARE_ADDRESS_LABEL(a_label) do { } while (0)
+#define ADJUST_ADDRESS_RANGE_FROM_RA(prange) do { } while (0)
+#endif  // __GNUC__
+
+//-----------------------------------------------------------------------//
+
+static void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)
+{
+  CHECK_GE(ret_addr, range.start);
+  CHECK_LE(ret_addr, range.end);
+}
+
+//-----------------------------------------------------------------------//
+
+void ATTRIBUTE_NOINLINE CheckStackTrace(int);
+static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {
+  const int STACK_LEN = 10;
+  void *stack[STACK_LEN];
+  int size;
+
+  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[1]);
+  INIT_ADDRESS_RANGE(CheckStackTraceLeaf, start, end, &expected_range[0]);
+  DECLARE_ADDRESS_LABEL(start);
+  size = GetStackTrace(stack, STACK_LEN, 0);
+  printf("Obtained %d stack frames.\n", size);
+  CHECK_GE(size, 1);
+  CHECK_LE(size, STACK_LEN);
+
+  if (1) {
+#ifdef HAVE_EXECINFO_H
+    char **strings = backtrace_symbols(stack, size);
+    printf("Obtained %d stack frames.\n", size);
+    for (int i = 0; i < size; i++)
+      printf("%s %p\n", strings[i], stack[i]);
+    printf("CheckStackTrace() addr: %p\n", &CheckStackTrace);
+    free(strings);
+#endif
+  }
+  for (int i = 0; i < BACKTRACE_STEPS; i++) {
+    printf("Backtrace %d: expected: %p..%p  actual: %p ... ",
+           i, expected_range[i].start, expected_range[i].end, stack[i]);
+    fflush(stdout);
+    CheckRetAddrIsInFunction(stack[i], expected_range[i]);
+    printf("OK\n");
+  }
+  DECLARE_ADDRESS_LABEL(end);
+}
+
+//-----------------------------------------------------------------------//
+
+/* Dummy functions to make the backtrace more interesting. */
+static void ATTRIBUTE_NOINLINE CheckStackTrace4(int i) {
+  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[2]);
+  INIT_ADDRESS_RANGE(CheckStackTrace4, start, end, &expected_range[1]);
+  DECLARE_ADDRESS_LABEL(start);
+  for (int j = i; j >= 0; j--)
+    CheckStackTraceLeaf();
+  DECLARE_ADDRESS_LABEL(end);
+}
+static void ATTRIBUTE_NOINLINE CheckStackTrace3(int i) {
+  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[3]);
+  INIT_ADDRESS_RANGE(CheckStackTrace3, start, end, &expected_range[2]);
+  DECLARE_ADDRESS_LABEL(start);
+  for (int j = i; j >= 0; j--)
+    CheckStackTrace4(j);
+  DECLARE_ADDRESS_LABEL(end);
+}
+static void ATTRIBUTE_NOINLINE CheckStackTrace2(int i) {
+  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[4]);
+  INIT_ADDRESS_RANGE(CheckStackTrace2, start, end, &expected_range[3]);
+  DECLARE_ADDRESS_LABEL(start);
+  for (int j = i; j >= 0; j--)
+    CheckStackTrace3(j);
+  DECLARE_ADDRESS_LABEL(end);
+}
+static void ATTRIBUTE_NOINLINE CheckStackTrace1(int i) {
+  ADJUST_ADDRESS_RANGE_FROM_RA(&expected_range[5]);
+  INIT_ADDRESS_RANGE(CheckStackTrace1, start, end, &expected_range[4]);
+  DECLARE_ADDRESS_LABEL(start);
+  for (int j = i; j >= 0; j--)
+    CheckStackTrace2(j);
+  DECLARE_ADDRESS_LABEL(end);
+}
+void ATTRIBUTE_NOINLINE CheckStackTrace(int i) {
+  INIT_ADDRESS_RANGE(CheckStackTrace, start, end, &expected_range[5]);
+  DECLARE_ADDRESS_LABEL(start);
+  for (int j = i; j >= 0; j--)
+    CheckStackTrace1(j);
+  DECLARE_ADDRESS_LABEL(end);
+}
+
+//-----------------------------------------------------------------------//
+
+int main(int, char ** argv) {
+  FLAGS_logtostderr = true;
+  InitGoogleLogging(argv[0]);
+
+  CheckStackTrace(0);
+
+  printf("PASS\n");
+  return 0;
+}
+
+#else
+int main() {
+  printf("PASS (no stacktrace support)\n");
+  return 0;
+}
+#endif  // HAVE_STACKTRACE
diff --git a/third_party/google-glog/src/stacktrace_windows-inl.h b/third_party/google-glog/src/stacktrace_windows-inl.h
new file mode 100644
index 0000000..7263188
--- /dev/null
+++ b/third_party/google-glog/src/stacktrace_windows-inl.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2000 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Andrew Schwartzmeyer
+//
+// Windows implementation - just use CaptureStackBackTrace
+
+#include "config.h"
+#include "port.h"
+#include "stacktrace.h"
+#include <DbgHelp.h>
+
+_START_GOOGLE_NAMESPACE_
+
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+  if (max_depth > 64) {
+    max_depth = 64;
+  }
+  skip_count++;  // we want to skip the current frame as well
+  // This API is thread-safe (moreover it walks only the current thread).
+  return CaptureStackBackTrace(skip_count, max_depth, result, NULL);
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_x86-inl.h b/third_party/google-glog/src/stacktrace_x86-inl.h
new file mode 100644
index 0000000..3b8d5a8
--- /dev/null
+++ b/third_party/google-glog/src/stacktrace_x86-inl.h
@@ -0,0 +1,146 @@
+// Copyright (c) 2000 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Produce stack trace
+
+#include <stdint.h>   // for uintptr_t
+
+#include "utilities.h"   // for OS_* macros
+
+#if !defined(OS_WINDOWS)
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+
+#include <stdio.h>  // for NULL
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// Given a pointer to a stack frame, locate and return the calling
+// stackframe, or return NULL if no stackframe can be found. Perform sanity
+// checks (the strictness of which is controlled by the boolean parameter
+// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
+template<bool STRICT_UNWINDING>
+static void **NextStackFrame(void **old_sp) {
+  void **new_sp = (void **) *old_sp;
+
+  // Check that the transition from frame pointer old_sp to frame
+  // pointer new_sp isn't clearly bogus
+  if (STRICT_UNWINDING) {
+    // With the stack growing downwards, older stack frame must be
+    // at a greater address that the current one.
+    if (new_sp <= old_sp) return NULL;
+    // Assume stack frames larger than 100,000 bytes are bogus.
+    if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
+  } else {
+    // In the non-strict mode, allow discontiguous stack frames.
+    // (alternate-signal-stacks for example).
+    if (new_sp == old_sp) return NULL;
+    // And allow frames upto about 1MB.
+    if ((new_sp > old_sp)
+        && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
+  }
+  if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;
+#ifdef __i386__
+  // On 64-bit machines, the stack pointer can be very close to
+  // 0xffffffff, so we explicitly check for a pointer into the
+  // last two pages in the address space
+  if ((uintptr_t)new_sp >= 0xffffe000) return NULL;
+#endif
+#if !defined(OS_WINDOWS)
+  if (!STRICT_UNWINDING) {
+    // Lax sanity checks cause a crash in 32-bit tcmalloc/crash_reason_test
+    // on AMD-based machines with VDSO-enabled kernels.
+    // Make an extra sanity check to insure new_sp is readable.
+    // Note: NextStackFrame<false>() is only called while the program
+    //       is already on its last leg, so it's ok to be slow here.
+    static int page_size = getpagesize();
+    void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1));
+    if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1)
+      return NULL;
+  }
+#endif
+  return new_sp;
+}
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+  void **sp;
+
+#ifdef __GNUC__
+#if __GNUC__ * 100 + __GNUC_MINOR__ >= 402
+#define USE_BUILTIN_FRAME_ADDRESS
+#endif
+#endif
+
+#ifdef USE_BUILTIN_FRAME_ADDRESS
+  sp = reinterpret_cast<void**>(__builtin_frame_address(0));
+#elif defined(__i386__)
+  // Stack frame format:
+  //    sp[0]   pointer to previous frame
+  //    sp[1]   caller address
+  //    sp[2]   first argument
+  //    ...
+  sp = (void **)&result - 2;
+#elif defined(__x86_64__)
+  // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8
+  unsigned long rbp;
+  // Move the value of the register %rbp into the local variable rbp.
+  // We need 'volatile' to prevent this instruction from getting moved
+  // around during optimization to before function prologue is done.
+  // An alternative way to achieve this
+  // would be (before this __asm__ instruction) to call Noop() defined as
+  //   static void Noop() __attribute__ ((noinline));  // prevent inlining
+  //   static void Noop() { asm(""); }  // prevent optimizing-away
+  __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
+  // Arguments are passed in registers on x86-64, so we can't just
+  // offset from &result
+  sp = (void **) rbp;
+#endif
+
+  int n = 0;
+  while (sp && n < max_depth) {
+    if (*(sp+1) == (void *)0) {
+      // In 64-bit code, we often see a frame that
+      // points to itself and has a return address of 0.
+      break;
+    }
+    if (skip_count > 0) {
+      skip_count--;
+    } else {
+      result[n++] = *(sp+1);
+    }
+    // Use strict unwinding rules.
+    sp = NextStackFrame<true>(sp);
+  }
+  return n;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stacktrace_x86_64-inl.h b/third_party/google-glog/src/stacktrace_x86_64-inl.h
new file mode 100644
index 0000000..f7d1dca
--- /dev/null
+++ b/third_party/google-glog/src/stacktrace_x86_64-inl.h
@@ -0,0 +1,105 @@
+// Copyright (c) 2005 - 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Arun Sharma
+//
+// Produce stack trace using libgcc
+
+extern "C" {
+#include <stdlib.h> // for NULL
+#include <unwind.h> // ABI defined unwinder
+}
+#include "stacktrace.h"
+
+_START_GOOGLE_NAMESPACE_
+
+typedef struct {
+  void **result;
+  int max_depth;
+  int skip_count;
+  int count;
+} trace_arg_t;
+
+
+// Workaround for the malloc() in _Unwind_Backtrace() issue.
+static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) {
+  return _URC_NO_REASON;
+}
+
+
+// This code is not considered ready to run until
+// static initializers run so that we are guaranteed
+// that any malloc-related initialization is done.
+static bool ready_to_run = false;
+class StackTraceInit {
+ public:
+   StackTraceInit() {
+     // Extra call to force initialization
+     _Unwind_Backtrace(nop_backtrace, NULL);
+     ready_to_run = true;
+   }
+};
+
+static StackTraceInit module_initializer;  // Force initialization
+
+static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
+  trace_arg_t *targ = (trace_arg_t *) opq;
+
+  if (targ->skip_count > 0) {
+    targ->skip_count--;
+  } else {
+    targ->result[targ->count++] = (void *) _Unwind_GetIP(uc);
+  }
+
+  if (targ->count == targ->max_depth)
+    return _URC_END_OF_STACK;
+
+  return _URC_NO_REASON;
+}
+
+// If you change this function, also change GetStackFrames below.
+int GetStackTrace(void** result, int max_depth, int skip_count) {
+  if (!ready_to_run)
+    return 0;
+
+  trace_arg_t targ;
+
+  skip_count += 1;         // Do not include the "GetStackTrace" frame
+
+  targ.result = result;
+  targ.max_depth = max_depth;
+  targ.skip_count = skip_count;
+  targ.count = 0;
+
+  _Unwind_Backtrace(GetOneFrame, &targ);
+
+  return targ.count;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/stl_logging_unittest.cc b/third_party/google-glog/src/stl_logging_unittest.cc
new file mode 100644
index 0000000..269094c
--- /dev/null
+++ b/third_party/google-glog/src/stl_logging_unittest.cc
@@ -0,0 +1,197 @@
+// Copyright (c) 2003, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#ifdef HAVE_USING_OPERATOR
+
+#include <functional>
+#include <iostream>
+#include <map>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#ifdef __GNUC__
+// C++0x isn't enabled by default in GCC and libc++ does not have
+// non-standard ext/* and tr1/unordered_*.
+# if defined(_LIBCPP_VERSION)
+#  ifndef GLOG_STL_LOGGING_FOR_UNORDERED
+#  define GLOG_STL_LOGGING_FOR_UNORDERED
+#  endif
+# else
+#  ifndef GLOG_STL_LOGGING_FOR_EXT_HASH
+#  define GLOG_STL_LOGGING_FOR_EXT_HASH
+#  endif
+#  ifndef GLOG_STL_LOGGING_FOR_EXT_SLIST
+#  define GLOG_STL_LOGGING_FOR_EXT_SLIST
+#  endif
+#  ifndef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
+#  define GLOG_STL_LOGGING_FOR_TR1_UNORDERED
+#  endif
+# endif
+#endif
+
+#include "glog/logging.h"
+#include "glog/stl_logging.h"
+#include "googletest.h"
+
+using namespace std;
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+using namespace __gnu_cxx;
+#endif
+
+struct user_hash {
+  size_t operator()(int x) const { return x; }
+};
+
+static void TestSTLLogging() {
+  {
+    // Test a sequence.
+    vector<int> v;
+    v.push_back(10);
+    v.push_back(20);
+    v.push_back(30);
+    ostringstream ss;
+    ss << v;
+    EXPECT_EQ(ss.str(), "10 20 30");
+    vector<int> copied_v(v);
+    CHECK_EQ(v, copied_v);  // This must compile.
+  }
+
+  {
+    // Test a sorted pair associative container.
+    map< int, string > m;
+    m[20] = "twenty";
+    m[10] = "ten";
+    m[30] = "thirty";
+    ostringstream ss;
+    ss << m;
+    EXPECT_EQ(ss.str(), "(10, ten) (20, twenty) (30, thirty)");
+    map< int, string > copied_m(m);
+    CHECK_EQ(m, copied_m);  // This must compile.
+  }
+
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+  {
+    // Test a hashed simple associative container.
+    hash_set<int> hs;
+    hs.insert(10);
+    hs.insert(20);
+    hs.insert(30);
+    ostringstream ss;
+    ss << hs;
+    EXPECT_EQ(ss.str(), "10 20 30");
+    hash_set<int> copied_hs(hs);
+    CHECK_EQ(hs, copied_hs);  // This must compile.
+  }
+#endif
+
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+  {
+    // Test a hashed pair associative container.
+    hash_map<int, string> hm;
+    hm[10] = "ten";
+    hm[20] = "twenty";
+    hm[30] = "thirty";
+    ostringstream ss;
+    ss << hm;
+    EXPECT_EQ(ss.str(), "(10, ten) (20, twenty) (30, thirty)");
+    hash_map<int, string> copied_hm(hm);
+    CHECK_EQ(hm, copied_hm);  // this must compile
+  }
+#endif
+
+  {
+    // Test a long sequence.
+    vector<int> v;
+    string expected;
+    for (int i = 0; i < 100; i++) {
+      v.push_back(i);
+      if (i > 0) expected += ' ';
+      char buf[256];
+      sprintf(buf, "%d", i);
+      expected += buf;
+    }
+    v.push_back(100);
+    expected += " ...";
+    ostringstream ss;
+    ss << v;
+    CHECK_EQ(ss.str(), expected.c_str());
+  }
+
+  {
+    // Test a sorted pair associative container.
+    // Use a non-default comparison functor.
+    map< int, string, greater<int> > m;
+    m[20] = "twenty";
+    m[10] = "ten";
+    m[30] = "thirty";
+    ostringstream ss;
+    ss << m;
+    EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)");
+    map< int, string, greater<int> > copied_m(m);
+    CHECK_EQ(m, copied_m);  // This must compile.
+  }
+
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+  {
+    // Test a hashed simple associative container.
+    // Use a user defined hash function.
+    hash_set<int, user_hash> hs;
+    hs.insert(10);
+    hs.insert(20);
+    hs.insert(30);
+    ostringstream ss;
+    ss << hs;
+    EXPECT_EQ(ss.str(), "10 20 30");
+    hash_set<int, user_hash> copied_hs(hs);
+    CHECK_EQ(hs, copied_hs);  // This must compile.
+  }
+#endif
+}
+
+int main(int, char**) {
+  TestSTLLogging();
+  std::cout << "PASS\n";
+  return 0;
+}
+
+#else
+
+#include <iostream>
+
+int main(int, char**) {
+  std::cout << "We don't support stl_logging for this compiler.\n"
+            << "(we need compiler support of 'using ::operator<<' "
+            << "for this feature.)\n";
+  return 0;
+}
+
+#endif  // HAVE_USING_OPERATOR
diff --git a/third_party/google-glog/src/symbolize.cc b/third_party/google-glog/src/symbolize.cc
new file mode 100644
index 0000000..1ffc607
--- /dev/null
+++ b/third_party/google-glog/src/symbolize.cc
@@ -0,0 +1,952 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+// Stack-footprint reduction work done by Raksit Ashok
+//
+// Implementation note:
+//
+// We don't use heaps but only use stacks.  We want to reduce the
+// stack consumption so that the symbolizer can run on small stacks.
+//
+// Here are some numbers collected with GCC 4.1.0 on x86:
+// - sizeof(Elf32_Sym)  = 16
+// - sizeof(Elf32_Shdr) = 40
+// - sizeof(Elf64_Sym)  = 24
+// - sizeof(Elf64_Shdr) = 64
+//
+// This implementation is intended to be async-signal-safe but uses
+// some functions which are not guaranteed to be so, such as memchr()
+// and memmove().  We assume they are async-signal-safe.
+//
+// Additional header can be specified by the GLOG_BUILD_CONFIG_INCLUDE
+// macro to add platform specific defines (e.g. OS_OPENBSD).
+
+#ifdef GLOG_BUILD_CONFIG_INCLUDE
+#include GLOG_BUILD_CONFIG_INCLUDE
+#endif  // GLOG_BUILD_CONFIG_INCLUDE
+
+#include "utilities.h"
+
+#if defined(HAVE_SYMBOLIZE)
+
+#include <string.h>
+
+#include <algorithm>
+#include <limits>
+
+#include "symbolize.h"
+#include "demangle.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// We don't use assert() since it's not guaranteed to be
+// async-signal-safe.  Instead we define a minimal assertion
+// macro. So far, we don't need pretty printing for __FILE__, etc.
+
+// A wrapper for abort() to make it callable in ? :.
+static int AssertFail() {
+  abort();
+  return 0;  // Should not reach.
+}
+
+#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
+
+static SymbolizeCallback g_symbolize_callback = NULL;
+void InstallSymbolizeCallback(SymbolizeCallback callback) {
+  g_symbolize_callback = callback;
+}
+
+static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback =
+    NULL;
+void InstallSymbolizeOpenObjectFileCallback(
+    SymbolizeOpenObjectFileCallback callback) {
+  g_symbolize_open_object_file_callback = callback;
+}
+
+// This function wraps the Demangle function to provide an interface
+// where the input symbol is demangled in-place.
+// To keep stack consumption low, we would like this function to not
+// get inlined.
+static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size) {
+  char demangled[256];  // Big enough for sane demangled symbols.
+  if (Demangle(out, demangled, sizeof(demangled))) {
+    // Demangling succeeded. Copy to out if the space allows.
+    size_t len = strlen(demangled);
+    if (len + 1 <= (size_t)out_size) {  // +1 for '\0'.
+      SAFE_ASSERT(len < sizeof(demangled));
+      memmove(out, demangled, len + 1);
+    }
+  }
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#if defined(__ELF__)
+
+#include <dlfcn.h>
+#if defined(OS_OPENBSD)
+#include <sys/exec_elf.h>
+#else
+#include <elf.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "symbolize.h"
+#include "config.h"
+#include "glog/raw_logging.h"
+
+// Re-runs fn until it doesn't cause EINTR.
+#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
+
+_START_GOOGLE_NAMESPACE_
+
+// Read up to "count" bytes from "offset" in the file pointed by file
+// descriptor "fd" into the buffer starting at "buf" while handling short reads
+// and EINTR.  On success, return the number of bytes read.  Otherwise, return
+// -1.
+static ssize_t ReadFromOffset(const int fd, void *buf, const size_t count,
+                              const off_t offset) {
+  SAFE_ASSERT(fd >= 0);
+  SAFE_ASSERT(count <= std::numeric_limits<ssize_t>::max());
+  char *buf0 = reinterpret_cast<char *>(buf);
+  ssize_t num_bytes = 0;
+  while (num_bytes < count) {
+    ssize_t len;
+    NO_INTR(len = pread(fd, buf0 + num_bytes, count - num_bytes,
+                        offset + num_bytes));
+    if (len < 0) {  // There was an error other than EINTR.
+      return -1;
+    }
+    if (len == 0) {  // Reached EOF.
+      break;
+    }
+    num_bytes += len;
+  }
+  SAFE_ASSERT(num_bytes <= count);
+  return num_bytes;
+}
+
+// Try reading exactly "count" bytes from "offset" bytes in a file
+// pointed by "fd" into the buffer starting at "buf" while handling
+// short reads and EINTR.  On success, return true. Otherwise, return
+// false.
+static bool ReadFromOffsetExact(const int fd, void *buf,
+                                const size_t count, const off_t offset) {
+  ssize_t len = ReadFromOffset(fd, buf, count, offset);
+  return len == count;
+}
+
+// Returns elf_header.e_type if the file pointed by fd is an ELF binary.
+static int FileGetElfType(const int fd) {
+  ElfW(Ehdr) elf_header;
+  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+    return -1;
+  }
+  if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) {
+    return -1;
+  }
+  return elf_header.e_type;
+}
+
+// Read the section headers in the given ELF binary, and if a section
+// of the specified type is found, set the output to this section header
+// and return true.  Otherwise, return false.
+// To keep stack consumption low, we would like this function to not get
+// inlined.
+static ATTRIBUTE_NOINLINE bool
+GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const off_t sh_offset,
+                       ElfW(Word) type, ElfW(Shdr) *out) {
+  // Read at most 16 section headers at a time to save read calls.
+  ElfW(Shdr) buf[16];
+  for (int i = 0; i < sh_num;) {
+    const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]);
+    const ssize_t num_bytes_to_read =
+        (sizeof(buf) > num_bytes_left) ? num_bytes_left : sizeof(buf);
+    const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read,
+                                       sh_offset + i * sizeof(buf[0]));
+    if (len == -1) {
+      return false;
+    }
+    SAFE_ASSERT(len % sizeof(buf[0]) == 0);
+    const ssize_t num_headers_in_buf = len / sizeof(buf[0]);
+    SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0]));
+    for (int j = 0; j < num_headers_in_buf; ++j) {
+      if (buf[j].sh_type == type) {
+        *out = buf[j];
+        return true;
+      }
+    }
+    i += num_headers_in_buf;
+  }
+  return false;
+}
+
+// There is no particular reason to limit section name to 63 characters,
+// but there has (as yet) been no need for anything longer either.
+const int kMaxSectionNameLen = 64;
+
+// name_len should include terminating '\0'.
+bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
+                            ElfW(Shdr) *out) {
+  ElfW(Ehdr) elf_header;
+  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+    return false;
+  }
+
+  ElfW(Shdr) shstrtab;
+  off_t shstrtab_offset = (elf_header.e_shoff +
+                           elf_header.e_shentsize * elf_header.e_shstrndx);
+  if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) {
+    return false;
+  }
+
+  for (int i = 0; i < elf_header.e_shnum; ++i) {
+    off_t section_header_offset = (elf_header.e_shoff +
+                                   elf_header.e_shentsize * i);
+    if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) {
+      return false;
+    }
+    char header_name[kMaxSectionNameLen];
+    if (sizeof(header_name) < name_len) {
+      RAW_LOG(WARNING, "Section name '%s' is too long (%" PRIuS "); "
+              "section will not be found (even if present).", name, name_len);
+      // No point in even trying.
+      return false;
+    }
+    off_t name_offset = shstrtab.sh_offset + out->sh_name;
+    ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset);
+    if (n_read == -1) {
+      return false;
+    } else if (n_read != name_len) {
+      // Short read -- name could be at end of file.
+      continue;
+    }
+    if (memcmp(header_name, name, name_len) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Read a symbol table and look for the symbol containing the
+// pc. Iterate over symbols in a symbol table and look for the symbol
+// containing "pc".  On success, return true and write the symbol name
+// to out.  Otherwise, return false.
+// To keep stack consumption low, we would like this function to not get
+// inlined.
+static ATTRIBUTE_NOINLINE bool
+FindSymbol(uint64_t pc, const int fd, char *out, int out_size,
+           uint64_t symbol_offset, const ElfW(Shdr) *strtab,
+           const ElfW(Shdr) *symtab) {
+  if (symtab == NULL) {
+    return false;
+  }
+  const int num_symbols = symtab->sh_size / symtab->sh_entsize;
+  for (int i = 0; i < num_symbols;) {
+    off_t offset = symtab->sh_offset + i * symtab->sh_entsize;
+
+    // If we are reading Elf64_Sym's, we want to limit this array to
+    // 32 elements (to keep stack consumption low), otherwise we can
+    // have a 64 element Elf32_Sym array.
+#if __WORDSIZE == 64
+#define NUM_SYMBOLS 32
+#else
+#define NUM_SYMBOLS 64
+#endif
+
+    // Read at most NUM_SYMBOLS symbols at once to save read() calls.
+    ElfW(Sym) buf[NUM_SYMBOLS];
+    int num_symbols_to_read = std::min(NUM_SYMBOLS, num_symbols - i);
+    const ssize_t len =
+        ReadFromOffset(fd, &buf, sizeof(buf[0]) * num_symbols_to_read, offset);
+    SAFE_ASSERT(len % sizeof(buf[0]) == 0);
+    const ssize_t num_symbols_in_buf = len / sizeof(buf[0]);
+    SAFE_ASSERT(num_symbols_in_buf <= num_symbols_to_read);
+    for (int j = 0; j < num_symbols_in_buf; ++j) {
+      const ElfW(Sym)& symbol = buf[j];
+      uint64_t start_address = symbol.st_value;
+      start_address += symbol_offset;
+      uint64_t end_address = start_address + symbol.st_size;
+      if (symbol.st_value != 0 &&  // Skip null value symbols.
+          symbol.st_shndx != 0 &&  // Skip undefined symbols.
+          start_address <= pc && pc < end_address) {
+        ssize_t len1 = ReadFromOffset(fd, out, out_size,
+                                      strtab->sh_offset + symbol.st_name);
+        if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) {
+          return false;
+        }
+        return true;  // Obtained the symbol name.
+      }
+    }
+    i += num_symbols_in_buf;
+  }
+  return false;
+}
+
+// Get the symbol name of "pc" from the file pointed by "fd".  Process
+// both regular and dynamic symbol tables if necessary.  On success,
+// write the symbol name to "out" and return true.  Otherwise, return
+// false.
+static bool GetSymbolFromObjectFile(const int fd,
+                                    uint64_t pc,
+                                    char* out,
+                                    int out_size,
+                                    uint64_t base_address) {
+  // Read the ELF header.
+  ElfW(Ehdr) elf_header;
+  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
+    return false;
+  }
+
+  ElfW(Shdr) symtab, strtab;
+
+  // Consult a regular symbol table first.
+  if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
+                             SHT_SYMTAB, &symtab)) {
+    if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
+                             symtab.sh_link * sizeof(symtab))) {
+      return false;
+    }
+    if (FindSymbol(pc, fd, out, out_size, base_address, &strtab, &symtab)) {
+      return true;  // Found the symbol in a regular symbol table.
+    }
+  }
+
+  // If the symbol is not found, then consult a dynamic symbol table.
+  if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
+                             SHT_DYNSYM, &symtab)) {
+    if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
+                             symtab.sh_link * sizeof(symtab))) {
+      return false;
+    }
+    if (FindSymbol(pc, fd, out, out_size, base_address, &strtab, &symtab)) {
+      return true;  // Found the symbol in a dynamic symbol table.
+    }
+  }
+
+  return false;
+}
+
+namespace {
+// Thin wrapper around a file descriptor so that the file descriptor
+// gets closed for sure.
+struct FileDescriptor {
+  const int fd_;
+  explicit FileDescriptor(int fd) : fd_(fd) {}
+  ~FileDescriptor() {
+    if (fd_ >= 0) {
+      NO_INTR(close(fd_));
+    }
+  }
+  int get() { return fd_; }
+
+ private:
+  explicit FileDescriptor(const FileDescriptor&);
+  void operator=(const FileDescriptor&);
+};
+
+// Helper class for reading lines from file.
+//
+// Note: we don't use ProcMapsIterator since the object is big (it has
+// a 5k array member) and uses async-unsafe functions such as sscanf()
+// and snprintf().
+class LineReader {
+ public:
+  explicit LineReader(int fd, char *buf, int buf_len, off_t offset)
+      : fd_(fd),
+        buf_(buf),
+        buf_len_(buf_len),
+        offset_(offset),
+        bol_(buf),
+        eol_(buf),
+        eod_(buf) {}
+
+  // Read '\n'-terminated line from file.  On success, modify "bol"
+  // and "eol", then return true.  Otherwise, return false.
+  //
+  // Note: if the last line doesn't end with '\n', the line will be
+  // dropped.  It's an intentional behavior to make the code simple.
+  bool ReadLine(const char **bol, const char **eol) {
+    if (BufferIsEmpty()) {  // First time.
+      const ssize_t num_bytes = ReadFromOffset(fd_, buf_, buf_len_, offset_);
+      if (num_bytes <= 0) {  // EOF or error.
+        return false;
+      }
+      offset_ += num_bytes;
+      eod_ = buf_ + num_bytes;
+      bol_ = buf_;
+    } else {
+      bol_ = eol_ + 1;  // Advance to the next line in the buffer.
+      SAFE_ASSERT(bol_ <= eod_);  // "bol_" can point to "eod_".
+      if (!HasCompleteLine()) {
+        const int incomplete_line_length = eod_ - bol_;
+        // Move the trailing incomplete line to the beginning.
+        memmove(buf_, bol_, incomplete_line_length);
+        // Read text from file and append it.
+        char * const append_pos = buf_ + incomplete_line_length;
+        const int capacity_left = buf_len_ - incomplete_line_length;
+        const ssize_t num_bytes =
+            ReadFromOffset(fd_, append_pos, capacity_left, offset_);
+        if (num_bytes <= 0) {  // EOF or error.
+          return false;
+        }
+        offset_ += num_bytes;
+        eod_ = append_pos + num_bytes;
+        bol_ = buf_;
+      }
+    }
+    eol_ = FindLineFeed();
+    if (eol_ == NULL) {  // '\n' not found.  Malformed line.
+      return false;
+    }
+    *eol_ = '\0';  // Replace '\n' with '\0'.
+
+    *bol = bol_;
+    *eol = eol_;
+    return true;
+  }
+
+  // Beginning of line.
+  const char *bol() {
+    return bol_;
+  }
+
+  // End of line.
+  const char *eol() {
+    return eol_;
+  }
+
+ private:
+  explicit LineReader(const LineReader&);
+  void operator=(const LineReader&);
+
+  char *FindLineFeed() {
+    return reinterpret_cast<char *>(memchr(bol_, '\n', eod_ - bol_));
+  }
+
+  bool BufferIsEmpty() {
+    return buf_ == eod_;
+  }
+
+  bool HasCompleteLine() {
+    return !BufferIsEmpty() && FindLineFeed() != NULL;
+  }
+
+  const int fd_;
+  char * const buf_;
+  const int buf_len_;
+  off_t offset_;
+  char *bol_;
+  char *eol_;
+  const char *eod_;  // End of data in "buf_".
+};
+}  // namespace
+
+// Place the hex number read from "start" into "*hex".  The pointer to
+// the first non-hex character or "end" is returned.
+static char *GetHex(const char *start, const char *end, uint64_t *hex) {
+  *hex = 0;
+  const char *p;
+  for (p = start; p < end; ++p) {
+    int ch = *p;
+    if ((ch >= '0' && ch <= '9') ||
+        (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
+      *hex = (*hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9);
+    } else {  // Encountered the first non-hex character.
+      break;
+    }
+  }
+  SAFE_ASSERT(p <= end);
+  return const_cast<char *>(p);
+}
+
+// Searches for the object file (from /proc/self/maps) that contains
+// the specified pc.  If found, sets |start_address| to the start address
+// of where this object file is mapped in memory, sets the module base
+// address into |base_address|, copies the object file name into
+// |out_file_name|, and attempts to open the object file.  If the object
+// file is opened successfully, returns the file descriptor.  Otherwise,
+// returns -1.  |out_file_name_size| is the size of the file name buffer
+// (including the null-terminator).
+static ATTRIBUTE_NOINLINE int
+OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
+                                             uint64_t &start_address,
+                                             uint64_t &base_address,
+                                             char *out_file_name,
+                                             int out_file_name_size) {
+  int object_fd;
+
+  int maps_fd;
+  NO_INTR(maps_fd = open("/proc/self/maps", O_RDONLY));
+  FileDescriptor wrapped_maps_fd(maps_fd);
+  if (wrapped_maps_fd.get() < 0) {
+    return -1;
+  }
+
+  int mem_fd;
+  NO_INTR(mem_fd = open("/proc/self/mem", O_RDONLY));
+  FileDescriptor wrapped_mem_fd(mem_fd);
+  if (wrapped_mem_fd.get() < 0) {
+    return -1;
+  }
+
+  // Iterate over maps and look for the map containing the pc.  Then
+  // look into the symbol tables inside.
+  char buf[1024];  // Big enough for line of sane /proc/self/maps
+  int num_maps = 0;
+  LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf), 0);
+  while (true) {
+    num_maps++;
+    const char *cursor;
+    const char *eol;
+    if (!reader.ReadLine(&cursor, &eol)) {  // EOF or malformed line.
+      return -1;
+    }
+
+    // Start parsing line in /proc/self/maps.  Here is an example:
+    //
+    // 08048000-0804c000 r-xp 00000000 08:01 2142121    /bin/cat
+    //
+    // We want start address (08048000), end address (0804c000), flags
+    // (r-xp) and file name (/bin/cat).
+
+    // Read start address.
+    cursor = GetHex(cursor, eol, &start_address);
+    if (cursor == eol || *cursor != '-') {
+      return -1;  // Malformed line.
+    }
+    ++cursor;  // Skip '-'.
+
+    // Read end address.
+    uint64_t end_address;
+    cursor = GetHex(cursor, eol, &end_address);
+    if (cursor == eol || *cursor != ' ') {
+      return -1;  // Malformed line.
+    }
+    ++cursor;  // Skip ' '.
+
+    // Read flags.  Skip flags until we encounter a space or eol.
+    const char * const flags_start = cursor;
+    while (cursor < eol && *cursor != ' ') {
+      ++cursor;
+    }
+    // We expect at least four letters for flags (ex. "r-xp").
+    if (cursor == eol || cursor < flags_start + 4) {
+      return -1;  // Malformed line.
+    }
+
+    // Determine the base address by reading ELF headers in process memory.
+    ElfW(Ehdr) ehdr;
+    // Skip non-readable maps.
+    if (flags_start[0] == 'r' &&
+        ReadFromOffsetExact(mem_fd, &ehdr, sizeof(ElfW(Ehdr)), start_address) &&
+        memcmp(ehdr.e_ident, ELFMAG, SELFMAG) == 0) {
+      switch (ehdr.e_type) {
+        case ET_EXEC:
+          base_address = 0;
+          break;
+        case ET_DYN:
+          // Find the segment containing file offset 0. This will correspond
+          // to the ELF header that we just read. Normally this will have
+          // virtual address 0, but this is not guaranteed. We must subtract
+          // the virtual address from the address where the ELF header was
+          // mapped to get the base address.
+          //
+          // If we fail to find a segment for file offset 0, use the address
+          // of the ELF header as the base address.
+          base_address = start_address;
+          for (unsigned i = 0; i != ehdr.e_phnum; ++i) {
+            ElfW(Phdr) phdr;
+            if (ReadFromOffsetExact(
+                    mem_fd, &phdr, sizeof(phdr),
+                    start_address + ehdr.e_phoff + i * sizeof(phdr)) &&
+                phdr.p_type == PT_LOAD && phdr.p_offset == 0) {
+              base_address = start_address - phdr.p_vaddr;
+              break;
+            }
+          }
+          break;
+        default:
+          // ET_REL or ET_CORE. These aren't directly executable, so they don't
+          // affect the base address.
+          break;
+      }
+    }
+
+    // Check start and end addresses.
+    if (!(start_address <= pc && pc < end_address)) {
+      continue;  // We skip this map.  PC isn't in this map.
+    }
+
+   // Check flags.  We are only interested in "r*x" maps.
+    if (flags_start[0] != 'r' || flags_start[2] != 'x') {
+      continue;  // We skip this map.
+    }
+    ++cursor;  // Skip ' '.
+
+    // Read file offset.
+    uint64_t file_offset;
+    cursor = GetHex(cursor, eol, &file_offset);
+    if (cursor == eol || *cursor != ' ') {
+      return -1;  // Malformed line.
+    }
+    ++cursor;  // Skip ' '.
+
+    // Skip to file name.  "cursor" now points to dev.  We need to
+    // skip at least two spaces for dev and inode.
+    int num_spaces = 0;
+    while (cursor < eol) {
+      if (*cursor == ' ') {
+        ++num_spaces;
+      } else if (num_spaces >= 2) {
+        // The first non-space character after skipping two spaces
+        // is the beginning of the file name.
+        break;
+      }
+      ++cursor;
+    }
+    if (cursor == eol) {
+      return -1;  // Malformed line.
+    }
+
+    // Finally, "cursor" now points to file name of our interest.
+    NO_INTR(object_fd = open(cursor, O_RDONLY));
+    if (object_fd < 0) {
+      // Failed to open object file.  Copy the object file name to
+      // |out_file_name|.
+      strncpy(out_file_name, cursor, out_file_name_size);
+      // Making sure |out_file_name| is always null-terminated.
+      out_file_name[out_file_name_size - 1] = '\0';
+      return -1;
+    }
+    return object_fd;
+  }
+}
+
+// POSIX doesn't define any async-signal safe function for converting
+// an integer to ASCII. We'll have to define our own version.
+// itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
+// conversion was successful or NULL otherwise. It never writes more than "sz"
+// bytes. Output will be truncated as needed, and a NUL character is always
+// appended.
+// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
+static char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) {
+  // Make sure we can write at least one NUL byte.
+  size_t n = 1;
+  if (n > sz)
+    return NULL;
+
+  if (base < 2 || base > 16) {
+    buf[0] = '\000';
+    return NULL;
+  }
+
+  char *start = buf;
+
+  uintptr_t j = i;
+
+  // Handle negative numbers (only for base 10).
+  if (i < 0 && base == 10) {
+    // This does "j = -i" while avoiding integer overflow.
+    j = static_cast<uintptr_t>(-(i + 1)) + 1;
+
+    // Make sure we can write the '-' character.
+    if (++n > sz) {
+      buf[0] = '\000';
+      return NULL;
+    }
+    *start++ = '-';
+  }
+
+  // Loop until we have converted the entire number. Output at least one
+  // character (i.e. '0').
+  char *ptr = start;
+  do {
+    // Make sure there is still enough space left in our output buffer.
+    if (++n > sz) {
+      buf[0] = '\000';
+      return NULL;
+    }
+
+    // Output the next digit.
+    *ptr++ = "0123456789abcdef"[j % base];
+    j /= base;
+
+    if (padding > 0)
+      padding--;
+  } while (j > 0 || padding > 0);
+
+  // Terminate the output with a NUL character.
+  *ptr = '\000';
+
+  // Conversion to ASCII actually resulted in the digits being in reverse
+  // order. We can't easily generate them in forward order, as we can't tell
+  // the number of characters needed until we are done converting.
+  // So, now, we reverse the string (except for the possible "-" sign).
+  while (--ptr > start) {
+    char ch = *ptr;
+    *ptr = *start;
+    *start++ = ch;
+  }
+  return buf;
+}
+
+// Safely appends string |source| to string |dest|.  Never writes past the
+// buffer size |dest_size| and guarantees that |dest| is null-terminated.
+static void SafeAppendString(const char* source, char* dest, int dest_size) {
+  int dest_string_length = strlen(dest);
+  SAFE_ASSERT(dest_string_length < dest_size);
+  dest += dest_string_length;
+  dest_size -= dest_string_length;
+  strncpy(dest, source, dest_size);
+  // Making sure |dest| is always null-terminated.
+  dest[dest_size - 1] = '\0';
+}
+
+// Converts a 64-bit value into a hex string, and safely appends it to |dest|.
+// Never writes past the buffer size |dest_size| and guarantees that |dest| is
+// null-terminated.
+static void SafeAppendHexNumber(uint64_t value, char* dest, int dest_size) {
+  // 64-bit numbers in hex can have up to 16 digits.
+  char buf[17] = {'\0'};
+  SafeAppendString(itoa_r(value, buf, sizeof(buf), 16, 0), dest, dest_size);
+}
+
+// The implementation of our symbolization routine.  If it
+// successfully finds the symbol containing "pc" and obtains the
+// symbol name, returns true and write the symbol name to "out".
+// Otherwise, returns false. If Callback function is installed via
+// InstallSymbolizeCallback(), the function is also called in this function,
+// and "out" is used as its output.
+// To keep stack consumption low, we would like this function to not
+// get inlined.
+static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
+                                                    int out_size) {
+  uint64_t pc0 = reinterpret_cast<uintptr_t>(pc);
+  uint64_t start_address = 0;
+  uint64_t base_address = 0;
+  int object_fd = -1;
+
+  if (out_size < 1) {
+    return false;
+  }
+  out[0] = '\0';
+  SafeAppendString("(", out, out_size);
+
+  if (g_symbolize_open_object_file_callback) {
+    object_fd = g_symbolize_open_object_file_callback(pc0, start_address,
+                                                      base_address, out + 1,
+                                                      out_size - 1);
+  } else {
+    object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, start_address,
+                                                             base_address,
+                                                             out + 1,
+                                                             out_size - 1);
+  }
+
+#if defined(PRINT_UNSYMBOLIZED_STACK_TRACES)
+  {
+    FileDescriptor wrapped_object_fd(object_fd);
+#else
+  // Check whether a file name was returned.
+  if (object_fd < 0) {
+#endif
+    if (out[1]) {
+      // The object file containing PC was determined successfully however the
+      // object file was not opened successfully.  This is still considered
+      // success because the object file name and offset are known and tools
+      // like asan_symbolize.py can be used for the symbolization.
+      out[out_size - 1] = '\0';  // Making sure |out| is always null-terminated.
+      SafeAppendString("+0x", out, out_size);
+      SafeAppendHexNumber(pc0 - base_address, out, out_size);
+      SafeAppendString(")", out, out_size);
+      return true;
+    }
+    // Failed to determine the object file containing PC.  Bail out.
+    return false;
+  }
+  FileDescriptor wrapped_object_fd(object_fd);
+  int elf_type = FileGetElfType(wrapped_object_fd.get());
+  if (elf_type == -1) {
+    return false;
+  }
+  if (g_symbolize_callback) {
+    // Run the call back if it's installed.
+    // Note: relocation (and much of the rest of this code) will be
+    // wrong for prelinked shared libraries and PIE executables.
+    uint64_t relocation = (elf_type == ET_DYN) ? start_address : 0;
+    int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(),
+                                                 pc, out, out_size,
+                                                 relocation);
+    if (num_bytes_written > 0) {
+      out += num_bytes_written;
+      out_size -= num_bytes_written;
+    }
+  }
+  if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0,
+                               out, out_size, base_address)) {
+    return false;
+  }
+
+  // Symbolization succeeded.  Now we try to demangle the symbol.
+  DemangleInplace(out, out_size);
+  return true;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#elif defined(OS_MACOSX) && defined(HAVE_DLADDR)
+
+#include <dlfcn.h>
+#include <string.h>
+
+_START_GOOGLE_NAMESPACE_
+
+static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
+                                                    int out_size) {
+  Dl_info info;
+  if (dladdr(pc, &info)) {
+    if ((int)strlen(info.dli_sname) < out_size) {
+      strcpy(out, info.dli_sname);
+      // Symbolization succeeded.  Now we try to demangle the symbol.
+      DemangleInplace(out, out_size);
+      return true;
+    }
+  }
+  return false;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#elif defined(OS_WINDOWS) || defined(OS_CYGWIN)
+
+#include <windows.h>
+#include <dbghelp.h>
+
+#ifdef _MSC_VER
+#pragma comment(lib, "dbghelp")
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+class SymInitializer {
+public:
+  HANDLE process;
+  bool ready;
+  SymInitializer() : process(NULL), ready(false) {
+    // Initialize the symbol handler.
+    // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx
+    process = GetCurrentProcess();
+    // Defer symbol loading.
+    // We do not request undecorated symbols with SYMOPT_UNDNAME
+    // because the mangling library calls UnDecorateSymbolName.
+    SymSetOptions(SYMOPT_DEFERRED_LOADS);
+    if (SymInitialize(process, NULL, true)) {
+      ready = true;
+    }
+  }
+  ~SymInitializer() {
+    SymCleanup(process);
+    // We do not need to close `HANDLE process` because it's a "pseudo handle."
+  }
+private:
+  SymInitializer(const SymInitializer&);
+  SymInitializer& operator=(const SymInitializer&);
+};
+
+static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
+                                                      int out_size) {
+  const static SymInitializer symInitializer;
+  if (!symInitializer.ready) {
+    return false;
+  }
+  // Resolve symbol information from address.
+  // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680578(v=vs.85).aspx
+  char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
+  SYMBOL_INFO *symbol = reinterpret_cast<SYMBOL_INFO *>(buf);
+  symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+  symbol->MaxNameLen = MAX_SYM_NAME;
+  // We use the ANSI version to ensure the string type is always `char *`.
+  // This could break if a symbol has Unicode in it.
+  BOOL ret = SymFromAddr(symInitializer.process,
+                         reinterpret_cast<DWORD64>(pc), 0, symbol);
+  if (ret == 1 && static_cast<int>(symbol->NameLen) < out_size) {
+    // `NameLen` does not include the null terminating character.
+    strncpy(out, symbol->Name, static_cast<size_t>(symbol->NameLen) + 1);
+    out[static_cast<size_t>(symbol->NameLen)] = '\0';
+    // Symbolization succeeded.  Now we try to demangle the symbol.
+    DemangleInplace(out, out_size);
+    return true;
+  }
+  return false;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#else
+# error BUG: HAVE_SYMBOLIZE was wrongly set
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+bool Symbolize(void *pc, char *out, int out_size) {
+  SAFE_ASSERT(out_size >= 0);
+  return SymbolizeAndDemangle(pc, out, out_size);
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#else  /* HAVE_SYMBOLIZE */
+
+#include <assert.h>
+
+#include "config.h"
+
+_START_GOOGLE_NAMESPACE_
+
+// TODO: Support other environments.
+bool Symbolize(void *pc, char *out, int out_size) {
+  assert(0);
+  return false;
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#endif
diff --git a/third_party/google-glog/src/symbolize.h b/third_party/google-glog/src/symbolize.h
new file mode 100644
index 0000000..c6f9ec4
--- /dev/null
+++ b/third_party/google-glog/src/symbolize.h
@@ -0,0 +1,158 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// This library provides Symbolize() function that symbolizes program
+// counters to their corresponding symbol names on linux platforms.
+// This library has a minimal implementation of an ELF symbol table
+// reader (i.e. it doesn't depend on libelf, etc.).
+//
+// The algorithm used in Symbolize() is as follows.
+//
+//   1. Go through a list of maps in /proc/self/maps and find the map
+//   containing the program counter.
+//
+//   2. Open the mapped file and find a regular symbol table inside.
+//   Iterate over symbols in the symbol table and look for the symbol
+//   containing the program counter.  If such a symbol is found,
+//   obtain the symbol name, and demangle the symbol if possible.
+//   If the symbol isn't found in the regular symbol table (binary is
+//   stripped), try the same thing with a dynamic symbol table.
+//
+// Note that Symbolize() is originally implemented to be used in
+// FailureSignalHandler() in base/google.cc.  Hence it doesn't use
+// malloc() and other unsafe operations.  It should be both
+// thread-safe and async-signal-safe.
+
+#ifndef BASE_SYMBOLIZE_H_
+#define BASE_SYMBOLIZE_H_
+
+#include "utilities.h"
+#include "config.h"
+#include "glog/logging.h"
+
+#ifdef HAVE_SYMBOLIZE
+
+#if defined(__ELF__)  // defined by gcc
+#if defined(__OpenBSD__)
+#include <sys/exec_elf.h>
+#else
+#include <elf.h>
+#endif
+
+#if !defined(ANDROID)
+#include <link.h>  // For ElfW() macro.
+#endif
+
+// For systems where SIZEOF_VOID_P is not defined, determine it
+// based on __LP64__ (defined by gcc on 64-bit systems)
+#if !defined(SIZEOF_VOID_P)
+# if defined(__LP64__)
+#  define SIZEOF_VOID_P 8
+# else
+#  define SIZEOF_VOID_P 4
+# endif
+#endif
+
+// If there is no ElfW macro, let's define it by ourself.
+#ifndef ElfW
+# if SIZEOF_VOID_P == 4
+#  define ElfW(type) Elf32_##type
+# elif SIZEOF_VOID_P == 8
+#  define ElfW(type) Elf64_##type
+# else
+#  error "Unknown sizeof(void *)"
+# endif
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+// Gets the section header for the given name, if it exists. Returns true on
+// success. Otherwise, returns false.
+bool GetSectionHeaderByName(int fd, const char *name, size_t name_len,
+                            ElfW(Shdr) *out);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif  /* __ELF__ */
+
+_START_GOOGLE_NAMESPACE_
+
+// Restrictions on the callbacks that follow:
+//  - The callbacks must not use heaps but only use stacks.
+//  - The callbacks must be async-signal-safe.
+
+// Installs a callback function, which will be called right before a symbol name
+// is printed. The callback is intended to be used for showing a file name and a
+// line number preceding a symbol name.
+// "fd" is a file descriptor of the object file containing the program
+// counter "pc". The callback function should write output to "out"
+// and return the size of the output written. On error, the callback
+// function should return -1.
+typedef int (*SymbolizeCallback)(int fd,
+                                 void* pc,
+                                 char* out,
+                                 size_t out_size,
+                                 uint64_t relocation);
+void InstallSymbolizeCallback(SymbolizeCallback callback);
+
+// Installs a callback function, which will be called instead of
+// OpenObjectFileContainingPcAndGetStartAddress.  The callback is expected
+// to searches for the object file (from /proc/self/maps) that contains
+// the specified pc.  If found, sets |start_address| to the start address
+// of where this object file is mapped in memory, sets the module base
+// address into |base_address|, copies the object file name into
+// |out_file_name|, and attempts to open the object file.  If the object
+// file is opened successfully, returns the file descriptor.  Otherwise,
+// returns -1.  |out_file_name_size| is the size of the file name buffer
+// (including the null-terminator).
+typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc,
+                                               uint64_t& start_address,
+                                               uint64_t& base_address,
+                                               char* out_file_name,
+                                               int out_file_name_size);
+void InstallSymbolizeOpenObjectFileCallback(
+    SymbolizeOpenObjectFileCallback callback);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+// Symbolizes a program counter.  On success, returns true and write the
+// symbol name to "out".  The symbol name is demangled if possible
+// (supports symbols generated by GCC 3.x or newer).  Otherwise,
+// returns false.
+GOOGLE_GLOG_DLL_DECL bool Symbolize(void *pc, char *out, int out_size);
+
+_END_GOOGLE_NAMESPACE_
+
+#endif  // BASE_SYMBOLIZE_H_
diff --git a/third_party/google-glog/src/symbolize_unittest.cc b/third_party/google-glog/src/symbolize_unittest.cc
new file mode 100644
index 0000000..9a17e7b
--- /dev/null
+++ b/third_party/google-glog/src/symbolize_unittest.cc
@@ -0,0 +1,425 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Satoru Takabayashi
+//
+// Unit tests for functions in symbolize.cc.
+
+#include "utilities.h"
+
+#include <signal.h>
+#include <iostream>
+
+#include "glog/logging.h"
+#include "symbolize.h"
+#include "googletest.h"
+#include "config.h"
+
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+using namespace GFLAGS_NAMESPACE;
+#endif
+
+using namespace std;
+using namespace GOOGLE_NAMESPACE;
+
+#if defined(HAVE_STACKTRACE)
+
+#define always_inline
+
+// A wrapper function for Symbolize() to make the unit test simple.
+static const char *TrySymbolize(void *pc) {
+  static char symbol[4096];
+  if (Symbolize(pc, symbol, sizeof(symbol))) {
+    return symbol;
+  } else {
+    return NULL;
+  }
+}
+
+# if defined(__ELF__)
+
+// This unit tests make sense only with GCC.
+// Uses lots of GCC specific features.
+#if defined(__GNUC__) && !defined(__OPENCC__)
+#  if __GNUC__ >= 4
+#    define TEST_WITH_MODERN_GCC
+#    if __i386__  // always_inline isn't supported for x86_64 with GCC 4.1.0.
+#      undef always_inline
+#      define always_inline __attribute__((always_inline))
+#      define HAVE_ALWAYS_INLINE
+#    endif  // __i386__
+#  else
+#  endif  // __GNUC__ >= 4
+#  if defined(__i386__) || defined(__x86_64__)
+#    define TEST_X86_32_AND_64 1
+#  endif  // defined(__i386__) || defined(__x86_64__)
+#endif
+
+// Make them C linkage to avoid mangled names.
+extern "C" {
+void nonstatic_func();
+void nonstatic_func() {
+  volatile int a = 0;
+  ++a;
+}
+
+static void static_func() {
+  volatile int a = 0;
+  ++a;
+}
+}
+
+TEST(Symbolize, Symbolize) {
+  // We do C-style cast since GCC 2.95.3 doesn't allow
+  // reinterpret_cast<void *>(&func).
+
+  // Compilers should give us pointers to them.
+  EXPECT_STREQ("nonstatic_func", TrySymbolize((void *)(&nonstatic_func)));
+
+  // The name of an internal linkage symbol is not specified; allow either a
+  // mangled or an unmangled name here.
+  const char *static_func_symbol = TrySymbolize((void *)(&static_func));
+  CHECK(NULL != static_func_symbol);
+  EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 ||
+              strcmp("static_func()", static_func_symbol) == 0);
+
+  EXPECT_TRUE(NULL == TrySymbolize(NULL));
+}
+
+struct Foo {
+  static void func(int x);
+};
+
+void ATTRIBUTE_NOINLINE Foo::func(int x) {
+  volatile int a = x;
+  ++a;
+}
+
+// With a modern GCC, Symbolize() should return demangled symbol
+// names.  Function parameters should be omitted.
+#ifdef TEST_WITH_MODERN_GCC
+TEST(Symbolize, SymbolizeWithDemangling) {
+  Foo::func(100);
+  EXPECT_STREQ("Foo::func()", TrySymbolize((void *)(&Foo::func)));
+}
+#endif
+
+// Tests that verify that Symbolize footprint is within some limit.
+
+// To measure the stack footprint of the Symbolize function, we create
+// a signal handler (for SIGUSR1 say) that calls the Symbolize function
+// on an alternate stack. This alternate stack is initialized to some
+// known pattern (0x55, 0x55, 0x55, ...). We then self-send this signal,
+// and after the signal handler returns, look at the alternate stack
+// buffer to see what portion has been touched.
+//
+// This trick gives us the the stack footprint of the signal handler.
+// But the signal handler, even before the call to Symbolize, consumes
+// some stack already. We however only want the stack usage of the
+// Symbolize function. To measure this accurately, we install two signal
+// handlers: one that does nothing and just returns, and another that
+// calls Symbolize. The difference between the stack consumption of these
+// two signals handlers should give us the Symbolize stack foorprint.
+
+static void *g_pc_to_symbolize;
+static char g_symbolize_buffer[4096];
+static char *g_symbolize_result;
+
+static void EmptySignalHandler(int signo) {}
+
+static void SymbolizeSignalHandler(int signo) {
+  if (Symbolize(g_pc_to_symbolize, g_symbolize_buffer,
+                sizeof(g_symbolize_buffer))) {
+    g_symbolize_result = g_symbolize_buffer;
+  } else {
+    g_symbolize_result = NULL;
+  }
+}
+
+const int kAlternateStackSize = 8096;
+const char kAlternateStackFillValue = 0x55;
+
+// These helper functions look at the alternate stack buffer, and figure
+// out what portion of this buffer has been touched - this is the stack
+// consumption of the signal handler running on this alternate stack.
+static ATTRIBUTE_NOINLINE bool StackGrowsDown(int *x) {
+  int y;
+  return &y < x;
+}
+static int GetStackConsumption(const char* alt_stack) {
+  int x;
+  if (StackGrowsDown(&x)) {
+    for (int i = 0; i < kAlternateStackSize; i++) {
+      if (alt_stack[i] != kAlternateStackFillValue) {
+        return (kAlternateStackSize - i);
+      }
+    }
+  } else {
+    for (int i = (kAlternateStackSize - 1); i >= 0; i--) {
+      if (alt_stack[i] != kAlternateStackFillValue) {
+        return i;
+      }
+    }
+  }
+  return -1;
+}
+
+#ifdef HAVE_SIGALTSTACK
+
+// Call Symbolize and figure out the stack footprint of this call.
+static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
+
+  g_pc_to_symbolize = pc;
+
+  // The alt-signal-stack cannot be heap allocated because there is a
+  // bug in glibc-2.2 where some signal handler setup code looks at the
+  // current stack pointer to figure out what thread is currently running.
+  // Therefore, the alternate stack must be allocated from the main stack
+  // itself.
+  char altstack[kAlternateStackSize];
+  memset(altstack, kAlternateStackFillValue, kAlternateStackSize);
+
+  // Set up the alt-signal-stack (and save the older one).
+  stack_t sigstk;
+  memset(&sigstk, 0, sizeof(stack_t));
+  stack_t old_sigstk;
+  sigstk.ss_sp = altstack;
+  sigstk.ss_size = kAlternateStackSize;
+  sigstk.ss_flags = 0;
+  CHECK_ERR(sigaltstack(&sigstk, &old_sigstk));
+
+  // Set up SIGUSR1 and SIGUSR2 signal handlers (and save the older ones).
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(struct sigaction));
+  struct sigaction old_sa1, old_sa2;
+  sigemptyset(&sa.sa_mask);
+  sa.sa_flags = SA_ONSTACK;
+
+  // SIGUSR1 maps to EmptySignalHandler.
+  sa.sa_handler = EmptySignalHandler;
+  CHECK_ERR(sigaction(SIGUSR1, &sa, &old_sa1));
+
+  // SIGUSR2 maps to SymbolizeSignalHanlder.
+  sa.sa_handler = SymbolizeSignalHandler;
+  CHECK_ERR(sigaction(SIGUSR2, &sa, &old_sa2));
+
+  // Send SIGUSR1 signal and measure the stack consumption of the empty
+  // signal handler.
+  CHECK_ERR(kill(getpid(), SIGUSR1));
+  int stack_consumption1 = GetStackConsumption(altstack);
+
+  // Send SIGUSR2 signal and measure the stack consumption of the symbolize
+  // signal handler.
+  CHECK_ERR(kill(getpid(), SIGUSR2));
+  int stack_consumption2 = GetStackConsumption(altstack);
+
+  // The difference between the two stack consumption values is the
+  // stack footprint of the Symbolize function.
+  if (stack_consumption1 != -1 && stack_consumption2 != -1) {
+    *stack_consumed = stack_consumption2 - stack_consumption1;
+  } else {
+    *stack_consumed = -1;
+  }
+
+  // Log the stack consumption values.
+  LOG(INFO) << "Stack consumption of empty signal handler: "
+            << stack_consumption1;
+  LOG(INFO) << "Stack consumption of symbolize signal handler: "
+            << stack_consumption2;
+  LOG(INFO) << "Stack consumption of Symbolize: " << *stack_consumed;
+
+  // Now restore the old alt-signal-stack and signal handlers.
+  CHECK_ERR(sigaltstack(&old_sigstk, NULL));
+  CHECK_ERR(sigaction(SIGUSR1, &old_sa1, NULL));
+  CHECK_ERR(sigaction(SIGUSR2, &old_sa2, NULL));
+
+  return g_symbolize_result;
+}
+
+#ifdef __ppc64__
+// Symbolize stack consumption should be within 4kB.
+const int kStackConsumptionUpperLimit = 4096;
+#else
+// Symbolize stack consumption should be within 2kB.
+const int kStackConsumptionUpperLimit = 2048;
+#endif
+
+TEST(Symbolize, SymbolizeStackConsumption) {
+  int stack_consumed;
+  const char* symbol;
+
+  symbol = SymbolizeStackConsumption((void *)(&nonstatic_func),
+                                     &stack_consumed);
+  EXPECT_STREQ("nonstatic_func", symbol);
+  EXPECT_GT(stack_consumed, 0);
+  EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
+
+  // The name of an internal linkage symbol is not specified; allow either a
+  // mangled or an unmangled name here.
+  symbol = SymbolizeStackConsumption((void *)(&static_func),
+                                     &stack_consumed);
+  CHECK(NULL != symbol);
+  EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
+              strcmp("static_func()", symbol) == 0);
+  EXPECT_GT(stack_consumed, 0);
+  EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
+}
+
+#ifdef TEST_WITH_MODERN_GCC
+TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) {
+  Foo::func(100);
+  int stack_consumed;
+  const char* symbol;
+
+  symbol = SymbolizeStackConsumption((void *)(&Foo::func), &stack_consumed);
+
+  EXPECT_STREQ("Foo::func()", symbol);
+  EXPECT_GT(stack_consumed, 0);
+  EXPECT_LT(stack_consumed, kStackConsumptionUpperLimit);
+}
+#endif
+
+#endif  // HAVE_SIGALTSTACK
+
+// x86 specific tests.  Uses some inline assembler.
+extern "C" {
+inline void* always_inline inline_func() {
+  void *pc = NULL;
+#ifdef TEST_X86_32_AND_64
+  __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
+#endif
+  return pc;
+}
+
+void* ATTRIBUTE_NOINLINE non_inline_func();
+void* ATTRIBUTE_NOINLINE non_inline_func() {
+  void *pc = NULL;
+#ifdef TEST_X86_32_AND_64
+  __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
+#endif
+  return pc;
+}
+
+static void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() {
+#if defined(TEST_X86_32_AND_64) && defined(HAVE_ATTRIBUTE_NOINLINE)
+  void *pc = non_inline_func();
+  const char *symbol = TrySymbolize(pc);
+  CHECK(symbol != NULL);
+  CHECK_STREQ(symbol, "non_inline_func");
+  cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl;
+#endif
+}
+
+static void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
+#if defined(TEST_X86_32_AND_64) && defined(HAVE_ALWAYS_INLINE)
+  void *pc = inline_func();  // Must be inlined.
+  const char *symbol = TrySymbolize(pc);
+  CHECK(symbol != NULL);
+  CHECK_STREQ(symbol, __FUNCTION__);
+  cout << "Test case TestWithPCInsideInlineFunction passed." << endl;
+#endif
+}
+}
+
+// Test with a return address.
+static void ATTRIBUTE_NOINLINE TestWithReturnAddress() {
+#if defined(HAVE_ATTRIBUTE_NOINLINE)
+  void *return_address = __builtin_return_address(0);
+  const char *symbol = TrySymbolize(return_address);
+  CHECK(symbol != NULL);
+  CHECK_STREQ(symbol, "main");
+  cout << "Test case TestWithReturnAddress passed." << endl;
+#endif
+}
+
+# elif defined(OS_WINDOWS) || defined(OS_CYGWIN)
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#pragma intrinsic(_ReturnAddress)
+#endif
+
+struct Foo {
+  static void func(int x);
+};
+
+__declspec(noinline) void Foo::func(int x) {
+  volatile int a = x;
+  ++a;
+}
+
+TEST(Symbolize, SymbolizeWithDemangling) {
+  Foo::func(100);
+  const char* ret = TrySymbolize((void *)(&Foo::func));
+  EXPECT_STREQ("public: static void __cdecl Foo::func(int)", ret);
+}
+
+__declspec(noinline) void TestWithReturnAddress() {
+  void *return_address =
+#ifdef __GNUC__ // Cygwin and MinGW support
+	  __builtin_return_address(0)
+#else
+	  _ReturnAddress()
+#endif
+	  ;
+  const char *symbol = TrySymbolize(return_address);
+  CHECK(symbol != NULL);
+  CHECK_STREQ(symbol, "main");
+  cout << "Test case TestWithReturnAddress passed." << endl;
+}
+# endif  // __ELF__
+#endif  // HAVE_STACKTRACE
+
+int main(int argc, char **argv) {
+  FLAGS_logtostderr = true;
+  InitGoogleLogging(argv[0]);
+  InitGoogleTest(&argc, argv);
+#if defined(HAVE_SYMBOLIZE)
+# if defined(__ELF__)
+  // We don't want to get affected by the callback interface, that may be
+  // used to install some callback function at InitGoogle() time.
+  InstallSymbolizeCallback(NULL);
+
+  TestWithPCInsideInlineFunction();
+  TestWithPCInsideNonInlineFunction();
+  TestWithReturnAddress();
+  return RUN_ALL_TESTS();
+# elif defined(OS_WINDOWS) || defined(OS_CYGWIN)
+  TestWithReturnAddress();
+  return RUN_ALL_TESTS();
+# else  // OS_WINDOWS
+  printf("PASS (no symbolize_unittest support)\n");
+  return 0;
+# endif  // __ELF__
+#else
+  printf("PASS (no symbolize support)\n");
+  return 0;
+#endif  // HAVE_SYMBOLIZE
+}
diff --git a/third_party/google-glog/src/utilities.cc b/third_party/google-glog/src/utilities.cc
new file mode 100644
index 0000000..25c4b76
--- /dev/null
+++ b/third_party/google-glog/src/utilities.cc
@@ -0,0 +1,384 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Shinichiro Hamaji
+
+#include "utilities.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <signal.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <time.h>
+#if defined(HAVE_SYSCALL_H)
+#include <syscall.h>                 // for syscall()
+#elif defined(HAVE_SYS_SYSCALL_H)
+#include <sys/syscall.h>                 // for syscall()
+#endif
+#ifdef HAVE_SYSLOG_H
+# include <syslog.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>  // For geteuid.
+#endif
+#ifdef HAVE_PWD_H
+# include <pwd.h>
+#endif
+
+#include "base/googleinit.h"
+
+using std::string;
+
+_START_GOOGLE_NAMESPACE_
+
+static const char* g_program_invocation_short_name = NULL;
+static pthread_t g_main_thread_id;
+
+_END_GOOGLE_NAMESPACE_
+
+// The following APIs are all internal.
+#ifdef HAVE_STACKTRACE
+
+#include "stacktrace.h"
+#include "symbolize.h"
+#include "base/commandlineflags.h"
+
+GLOG_DEFINE_bool(symbolize_stacktrace, true,
+                 "Symbolize the stack trace in the tombstone");
+
+_START_GOOGLE_NAMESPACE_
+
+typedef void DebugWriter(const char*, void*);
+
+// The %p field width for printf() functions is two characters per byte.
+// For some environments, add two extra bytes for the leading "0x".
+static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*);
+
+static void DebugWriteToStderr(const char* data, void *) {
+  // This one is signal-safe.
+  if (write(STDERR_FILENO, data, strlen(data)) < 0) {
+    // Ignore errors.
+  }
+}
+
+static void DebugWriteToString(const char* data, void *arg) {
+  reinterpret_cast<string*>(arg)->append(data);
+}
+
+#ifdef HAVE_SYMBOLIZE
+// Print a program counter and its symbol name.
+static void DumpPCAndSymbol(DebugWriter *writerfn, void *arg, void *pc,
+                            const char * const prefix) {
+  char tmp[1024];
+  const char *symbol = "(unknown)";
+  // Symbolizes the previous address of pc because pc may be in the
+  // next function.  The overrun happens when the function ends with
+  // a call to a function annotated noreturn (e.g. CHECK).
+  if (Symbolize(reinterpret_cast<char *>(pc) - 1, tmp, sizeof(tmp))) {
+      symbol = tmp;
+  }
+  char buf[1024];
+  snprintf(buf, sizeof(buf), "%s@ %*p  %s\n",
+           prefix, kPrintfPointerFieldWidth, pc, symbol);
+  writerfn(buf, arg);
+}
+#endif
+
+static void DumpPC(DebugWriter *writerfn, void *arg, void *pc,
+                   const char * const prefix) {
+  char buf[100];
+  snprintf(buf, sizeof(buf), "%s@ %*p\n",
+           prefix, kPrintfPointerFieldWidth, pc);
+  writerfn(buf, arg);
+}
+
+// Dump current stack trace as directed by writerfn
+static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) {
+  // Print stack trace
+  void* stack[32];
+  int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1);
+  for (int i = 0; i < depth; i++) {
+#if defined(HAVE_SYMBOLIZE)
+    if (FLAGS_symbolize_stacktrace) {
+      DumpPCAndSymbol(writerfn, arg, stack[i], "    ");
+    } else {
+      DumpPC(writerfn, arg, stack[i], "    ");
+    }
+#else
+    DumpPC(writerfn, arg, stack[i], "    ");
+#endif
+  }
+}
+
+static void DumpStackTraceAndExit() {
+  DumpStackTrace(1, DebugWriteToStderr, NULL);
+
+  // TOOD(hamaji): Use signal instead of sigaction?
+  if (IsFailureSignalHandlerInstalled()) {
+    // Set the default signal handler for SIGABRT, to avoid invoking our
+    // own signal handler installed by InstallFailureSignalHandler().
+#ifdef HAVE_SIGACTION
+    struct sigaction sig_action;
+    memset(&sig_action, 0, sizeof(sig_action));
+    sigemptyset(&sig_action.sa_mask);
+    sig_action.sa_handler = SIG_DFL;
+    sigaction(SIGABRT, &sig_action, NULL);
+#elif defined(OS_WINDOWS)
+    signal(SIGABRT, SIG_DFL);
+#endif  // HAVE_SIGACTION
+  }
+
+  abort();
+}
+
+_END_GOOGLE_NAMESPACE_
+
+#endif  // HAVE_STACKTRACE
+
+_START_GOOGLE_NAMESPACE_
+
+namespace glog_internal_namespace_ {
+
+const char* ProgramInvocationShortName() {
+  if (g_program_invocation_short_name != NULL) {
+    return g_program_invocation_short_name;
+  } else {
+    // TODO(hamaji): Use /proc/self/cmdline and so?
+    return "UNKNOWN";
+  }
+}
+
+bool IsGoogleLoggingInitialized() {
+  return g_program_invocation_short_name != NULL;
+}
+
+bool is_default_thread() {
+  if (g_program_invocation_short_name == NULL) {
+    // InitGoogleLogging() not yet called, so unlikely to be in a different
+    // thread
+    return true;
+  } else {
+    return pthread_equal(pthread_self(), g_main_thread_id);
+  }
+}
+
+#ifdef OS_WINDOWS
+struct timeval {
+  long tv_sec, tv_usec;
+};
+
+// Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd
+// See COPYING for copyright information.
+static int gettimeofday(struct timeval *tv, void* tz) {
+#define EPOCHFILETIME (116444736000000000ULL)
+  FILETIME ft;
+  LARGE_INTEGER li;
+  uint64 tt;
+
+  GetSystemTimeAsFileTime(&ft);
+  li.LowPart = ft.dwLowDateTime;
+  li.HighPart = ft.dwHighDateTime;
+  tt = (li.QuadPart - EPOCHFILETIME) / 10;
+  tv->tv_sec = tt / 1000000;
+  tv->tv_usec = tt % 1000000;
+
+  return 0;
+}
+#endif
+
+int64 CycleClock_Now() {
+  // TODO(hamaji): temporary impementation - it might be too slow.
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
+}
+
+int64 UsecToCycles(int64 usec) {
+  return usec;
+}
+
+WallTime WallTime_Now() {
+  // Now, cycle clock is retuning microseconds since the epoch.
+  return CycleClock_Now() * 0.000001;
+}
+
+static int32 g_main_thread_pid = getpid();
+int32 GetMainThreadPid() {
+  return g_main_thread_pid;
+}
+
+bool PidHasChanged() {
+  int32 pid = getpid();
+  if (g_main_thread_pid == pid) {
+    return false;
+  }
+  g_main_thread_pid = pid;
+  return true;
+}
+
+pid_t GetTID() {
+  // On Linux and MacOSX, we try to use gettid().
+#if defined OS_LINUX || defined OS_MACOSX
+#ifndef __NR_gettid
+#ifdef OS_MACOSX
+#define __NR_gettid SYS_gettid
+#elif ! defined __i386__
+#error "Must define __NR_gettid for non-x86 platforms"
+#else
+#define __NR_gettid 224
+#endif
+#endif
+  static bool lacks_gettid = false;
+  if (!lacks_gettid) {
+    pid_t tid = syscall(__NR_gettid);
+    if (tid != -1) {
+      return tid;
+    }
+    // Technically, this variable has to be volatile, but there is a small
+    // performance penalty in accessing volatile variables and there should
+    // not be any serious adverse effect if a thread does not immediately see
+    // the value change to "true".
+    lacks_gettid = true;
+  }
+#endif  // OS_LINUX || OS_MACOSX
+
+  // If gettid() could not be used, we use one of the following.
+#if defined OS_LINUX
+  return getpid();  // Linux:  getpid returns thread ID when gettid is absent
+#elif defined OS_WINDOWS && !defined OS_CYGWIN
+  return GetCurrentThreadId();
+#else
+  // If none of the techniques above worked, we use pthread_self().
+  return (pid_t)(uintptr_t)pthread_self();
+#endif
+}
+
+const char* const_basename(const char* filepath) {
+  const char* base = strrchr(filepath, '/');
+#ifdef OS_WINDOWS  // Look for either path separator in Windows
+  if (!base)
+    base = strrchr(filepath, '\\');
+#endif
+  return base ? (base+1) : filepath;
+}
+
+static string g_my_user_name;
+const string& MyUserName() {
+  return g_my_user_name;
+}
+static void MyUserNameInitializer() {
+  // TODO(hamaji): Probably this is not portable.
+#if defined(OS_WINDOWS)
+  const char* user = getenv("USERNAME");
+#else
+  const char* user = getenv("USER");
+#endif
+  if (user != NULL) {
+    g_my_user_name = user;
+  } else {
+#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H)
+    struct passwd pwd;
+    struct passwd* result = NULL;
+    char buffer[1024] = {'\0'};
+    uid_t uid = geteuid();
+    int pwuid_res = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result);
+    if (pwuid_res == 0) {
+      g_my_user_name = pwd.pw_name;
+    } else {
+      snprintf(buffer, sizeof(buffer), "uid%d", uid);
+      g_my_user_name = buffer;
+    }
+#endif
+    if (g_my_user_name.empty()) {
+      g_my_user_name = "invalid-user";
+    }
+  }
+
+}
+REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer());
+
+#ifdef HAVE_STACKTRACE
+void DumpStackTraceToString(string* stacktrace) {
+  DumpStackTrace(1, DebugWriteToString, stacktrace);
+}
+#endif
+
+// We use an atomic operation to prevent problems with calling CrashReason
+// from inside the Mutex implementation (potentially through RAW_CHECK).
+static const CrashReason* g_reason = 0;
+
+void SetCrashReason(const CrashReason* r) {
+  sync_val_compare_and_swap(&g_reason,
+                            reinterpret_cast<const CrashReason*>(0),
+                            r);
+}
+
+void InitGoogleLoggingUtilities(const char* argv0) {
+  CHECK(!IsGoogleLoggingInitialized())
+      << "You called InitGoogleLogging() twice!";
+  const char* slash = strrchr(argv0, '/');
+#ifdef OS_WINDOWS
+  if (!slash)  slash = strrchr(argv0, '\\');
+#endif
+  g_program_invocation_short_name = slash ? slash + 1 : argv0;
+  g_main_thread_id = pthread_self();
+
+#ifdef HAVE_STACKTRACE
+  InstallFailureFunction(&DumpStackTraceAndExit);
+#endif
+}
+
+void ShutdownGoogleLoggingUtilities() {
+  CHECK(IsGoogleLoggingInitialized())
+      << "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!";
+  g_program_invocation_short_name = NULL;
+#ifdef HAVE_SYSLOG_H
+  closelog();
+#endif
+}
+
+}  // namespace glog_internal_namespace_
+
+_END_GOOGLE_NAMESPACE_
+
+// Make an implementation of stacktrace compiled.
+#ifdef STACKTRACE_H
+# include STACKTRACE_H
+# if 0
+// For include scanners which can't handle macro expansions.
+#  include "stacktrace_libunwind-inl.h"
+#  include "stacktrace_x86-inl.h"
+#  include "stacktrace_x86_64-inl.h"
+#  include "stacktrace_powerpc-inl.h"
+#  include "stacktrace_generic-inl.h"
+# endif
+#endif
diff --git a/third_party/google-glog/src/utilities.h b/third_party/google-glog/src/utilities.h
new file mode 100644
index 0000000..ca21cfb
--- /dev/null
+++ b/third_party/google-glog/src/utilities.h
@@ -0,0 +1,240 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Shinichiro Hamaji
+//
+// Define utilties for glog internal usage.
+
+#ifndef UTILITIES_H__
+#define UTILITIES_H__
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+# define OS_WINDOWS
+#elif defined(__CYGWIN__) || defined(__CYGWIN32__)
+# define OS_CYGWIN
+#elif defined(linux) || defined(__linux) || defined(__linux__)
+# ifndef OS_LINUX
+#  define OS_LINUX
+# endif
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+# define OS_MACOSX
+#elif defined(__FreeBSD__)
+# define OS_FREEBSD
+#elif defined(__NetBSD__)
+# define OS_NETBSD
+#elif defined(__OpenBSD__)
+# define OS_OPENBSD
+#else
+// TODO(hamaji): Add other platforms.
+#endif
+
+// printf macros for size_t, in the style of inttypes.h
+#ifdef _LP64
+#define __PRIS_PREFIX "z"
+#else
+#define __PRIS_PREFIX
+#endif
+
+// Use these macros after a % in a printf format string
+// to get correct 32/64 bit behavior, like this:
+// size_t size = records.size();
+// printf("%"PRIuS"\n", size);
+
+#define PRIdS __PRIS_PREFIX "d"
+#define PRIxS __PRIS_PREFIX "x"
+#define PRIuS __PRIS_PREFIX "u"
+#define PRIXS __PRIS_PREFIX "X"
+#define PRIoS __PRIS_PREFIX "o"
+
+#include "base/mutex.h"  // This must go first so we get _XOPEN_SOURCE
+
+#include <string>
+
+#if defined(OS_WINDOWS)
+# include "port.h"
+#endif
+
+#include "config.h"
+#include "glog/logging.h"
+
+// There are three different ways we can try to get the stack trace:
+//
+// 1) The libunwind library.  This is still in development, and as a
+//    separate library adds a new dependency, but doesn't need a frame
+//    pointer.  It also doesn't call malloc.
+//
+// 2) Our hand-coded stack-unwinder.  This depends on a certain stack
+//    layout, which is used by gcc (and those systems using a
+//    gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
+//    It uses the frame pointer to do its work.
+//
+// 3) The gdb unwinder -- also the one used by the c++ exception code.
+//    It's obviously well-tested, but has a fatal flaw: it can call
+//    malloc() from the unwinder.  This is a problem because we're
+//    trying to use the unwinder to instrument malloc().
+//
+// 4) The Windows API CaptureStackTrace.
+//
+// Note: if you add a new implementation here, make sure it works
+// correctly when GetStackTrace() is called with max_depth == 0.
+// Some code may do that.
+
+#if defined(HAVE_LIB_UNWIND)
+# define STACKTRACE_H "stacktrace_libunwind-inl.h"
+#elif !defined(NO_FRAME_POINTER)
+# if defined(__i386__) && __GNUC__ >= 2
+#  define STACKTRACE_H "stacktrace_x86-inl.h"
+# elif defined(__x86_64__) && __GNUC__ >= 2 && HAVE_UNWIND_H
+#  define STACKTRACE_H "stacktrace_x86_64-inl.h"
+# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
+#  define STACKTRACE_H "stacktrace_powerpc-inl.h"
+# elif defined(OS_WINDOWS)
+#  define STACKTRACE_H "stacktrace_windows-inl.h"
+# endif
+#endif
+
+#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H)
+# define STACKTRACE_H "stacktrace_generic-inl.h"
+#endif
+
+#if defined(STACKTRACE_H)
+# define HAVE_STACKTRACE
+#endif
+
+#ifndef HAVE_SYMBOLIZE
+// defined by gcc
+#if defined(__ELF__) && defined(OS_LINUX)
+# define HAVE_SYMBOLIZE
+#elif defined(OS_MACOSX) && defined(HAVE_DLADDR)
+// Use dladdr to symbolize.
+# define HAVE_SYMBOLIZE
+#elif defined(OS_WINDOWS)
+// Use DbgHelp to symbolize
+# define HAVE_SYMBOLIZE
+#endif
+#endif // !defined(HAVE_SYMBOLIZE)
+
+#ifndef ARRAYSIZE
+// There is a better way, but this is good enough for our purpose.
+# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
+#endif
+
+_START_GOOGLE_NAMESPACE_
+
+namespace glog_internal_namespace_ {
+
+#ifdef HAVE___ATTRIBUTE__
+# define ATTRIBUTE_NOINLINE __attribute__ ((noinline))
+# define HAVE_ATTRIBUTE_NOINLINE
+#elif defined(OS_WINDOWS)
+# define ATTRIBUTE_NOINLINE __declspec(noinline)
+# define HAVE_ATTRIBUTE_NOINLINE
+#else
+# define ATTRIBUTE_NOINLINE
+#endif
+
+const char* ProgramInvocationShortName();
+
+bool IsGoogleLoggingInitialized();
+
+bool is_default_thread();
+
+int64 CycleClock_Now();
+
+int64 UsecToCycles(int64 usec);
+
+typedef double WallTime;
+WallTime WallTime_Now();
+
+int32 GetMainThreadPid();
+bool PidHasChanged();
+
+pid_t GetTID();
+
+const std::string& MyUserName();
+
+// Get the part of filepath after the last path separator.
+// (Doesn't modify filepath, contrary to basename() in libgen.h.)
+const char* const_basename(const char* filepath);
+
+// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't
+// defined, we try the CPU specific logics (we only support x86 and
+// x86_64 for now) first, then use a naive implementation, which has a
+// race condition.
+template<typename T>
+inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
+#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP)
+  return __sync_val_compare_and_swap(ptr, oldval, newval);
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+  T ret;
+  __asm__ __volatile__("lock; cmpxchg %1, (%2);"
+                       :"=a"(ret)
+                        // GCC may produces %sil or %dil for
+                        // constraint "r", but some of apple's gas
+                        // dosn't know the 8 bit registers.
+                        // We use "q" to avoid these registers.
+                       :"q"(newval), "q"(ptr), "a"(oldval)
+                       :"memory", "cc");
+  return ret;
+#else
+  T ret = *ptr;
+  if (ret == oldval) {
+    *ptr = newval;
+  }
+  return ret;
+#endif
+}
+
+void DumpStackTraceToString(std::string* stacktrace);
+
+struct CrashReason {
+  CrashReason() : filename(0), line_number(0), message(0), depth(0) {}
+
+  const char* filename;
+  int line_number;
+  const char* message;
+
+  // We'll also store a bit of stack trace context at the time of crash as
+  // it may not be available later on.
+  void* stack[32];
+  int depth;
+};
+
+void SetCrashReason(const CrashReason* r);
+
+void InitGoogleLoggingUtilities(const char* argv0);
+void ShutdownGoogleLoggingUtilities();
+
+}  // namespace glog_internal_namespace_
+
+_END_GOOGLE_NAMESPACE_
+
+using namespace GOOGLE_NAMESPACE::glog_internal_namespace_;
+
+#endif  // UTILITIES_H__
diff --git a/third_party/google-glog/src/utilities_unittest.cc b/third_party/google-glog/src/utilities_unittest.cc
new file mode 100644
index 0000000..38e847d
--- /dev/null
+++ b/third_party/google-glog/src/utilities_unittest.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Shinichiro Hamaji
+#include "utilities.h"
+#include "googletest.h"
+#include "glog/logging.h"
+
+#ifdef HAVE_LIB_GFLAGS
+#include <gflags/gflags.h>
+using namespace GFLAGS_NAMESPACE;
+#endif
+
+using namespace GOOGLE_NAMESPACE;
+
+TEST(utilities, sync_val_compare_and_swap) {
+  bool now_entering = false;
+  EXPECT_FALSE(sync_val_compare_and_swap(&now_entering, false, true));
+  EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true));
+  EXPECT_TRUE(sync_val_compare_and_swap(&now_entering, false, true));
+}
+
+TEST(utilities, InitGoogleLoggingDeathTest) {
+  ASSERT_DEATH(InitGoogleLogging("foobar"), "");
+}
+
+int main(int argc, char **argv) {
+  InitGoogleLogging(argv[0]);
+  InitGoogleTest(&argc, argv);
+
+  CHECK_EQ(RUN_ALL_TESTS(), 0);
+}
diff --git a/third_party/google-glog/src/vlog_is_on.cc b/third_party/google-glog/src/vlog_is_on.cc
new file mode 100644
index 0000000..e8fdbae
--- /dev/null
+++ b/third_party/google-glog/src/vlog_is_on.cc
@@ -0,0 +1,257 @@
+// Copyright (c) 1999, 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney and many others
+//
+// Broken out from logging.cc by Soren Lassen
+// logging_unittest.cc covers the functionality herein
+
+#include "utilities.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <cstdio>
+#include <string>
+#include "base/commandlineflags.h"
+#include "glog/logging.h"
+#include "glog/raw_logging.h"
+#include "base/googleinit.h"
+
+// glog doesn't have annotation
+#define ANNOTATE_BENIGN_RACE(address, description)
+
+using std::string;
+
+GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this."
+" Overridable by --vmodule.");
+
+GLOG_DEFINE_string(vmodule, "", "per-module verbose level."
+" Argument is a comma-separated list of <module name>=<log level>."
+" <module name> is a glob pattern, matched against the filename base"
+" (that is, name ignoring .cc/.h./-inl.h)."
+" <log level> overrides any value given by --v.");
+
+_START_GOOGLE_NAMESPACE_
+
+namespace glog_internal_namespace_ {
+
+// Used by logging_unittests.cc so can't make it static here.
+GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern,
+                                       size_t patt_len,
+                                       const char* str,
+                                       size_t str_len);
+
+// Implementation of fnmatch that does not need 0-termination
+// of arguments and does not allocate any memory,
+// but we only support "*" and "?" wildcards, not the "[...]" patterns.
+// It's not a static function for the unittest.
+GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern,
+                                       size_t patt_len,
+                                       const char* str,
+                                       size_t str_len) {
+  size_t p = 0;
+  size_t s = 0;
+  while (1) {
+    if (p == patt_len  &&  s == str_len) return true;
+    if (p == patt_len) return false;
+    if (s == str_len) return p+1 == patt_len  &&  pattern[p] == '*';
+    if (pattern[p] == str[s]  ||  pattern[p] == '?') {
+      p += 1;
+      s += 1;
+      continue;
+    }
+    if (pattern[p] == '*') {
+      if (p+1 == patt_len) return true;
+      do {
+        if (SafeFNMatch_(pattern+(p+1), patt_len-(p+1), str+s, str_len-s)) {
+          return true;
+        }
+        s += 1;
+      } while (s != str_len);
+      return false;
+    }
+    return false;
+  }
+}
+
+}  // namespace glog_internal_namespace_
+
+using glog_internal_namespace_::SafeFNMatch_;
+
+int32 kLogSiteUninitialized = 1000;
+
+// List of per-module log levels from FLAGS_vmodule.
+// Once created each element is never deleted/modified
+// except for the vlog_level: other threads will read VModuleInfo blobs
+// w/o locks and we'll store pointers to vlog_level at VLOG locations
+// that will never go away.
+// We can't use an STL struct here as we wouldn't know
+// when it's safe to delete/update it: other threads need to use it w/o locks.
+struct VModuleInfo {
+  string module_pattern;
+  mutable int32 vlog_level;  // Conceptually this is an AtomicWord, but it's
+                             // too much work to use AtomicWord type here
+                             // w/o much actual benefit.
+  const VModuleInfo* next;
+};
+
+// This protects the following global variables.
+static Mutex vmodule_lock;
+// Pointer to head of the VModuleInfo list.
+// It's a map from module pattern to logging level for those module(s).
+static VModuleInfo* vmodule_list = 0;
+// Boolean initialization flag.
+static bool inited_vmodule = false;
+
+// L >= vmodule_lock.
+static void VLOG2Initializer() {
+  vmodule_lock.AssertHeld();
+  // Can now parse --vmodule flag and initialize mapping of module-specific
+  // logging levels.
+  inited_vmodule = false;
+  const char* vmodule = FLAGS_vmodule.c_str();
+  const char* sep;
+  VModuleInfo* head = NULL;
+  VModuleInfo* tail = NULL;
+  while ((sep = strchr(vmodule, '=')) != NULL) {
+    string pattern(vmodule, sep - vmodule);
+    int module_level;
+    if (sscanf(sep, "=%d", &module_level) == 1) {
+      VModuleInfo* info = new VModuleInfo;
+      info->module_pattern = pattern;
+      info->vlog_level = module_level;
+      if (head)  tail->next = info;
+      else  head = info;
+      tail = info;
+    }
+    // Skip past this entry
+    vmodule = strchr(sep, ',');
+    if (vmodule == NULL) break;
+    vmodule++;  // Skip past ","
+  }
+  if (head) {  // Put them into the list at the head:
+    tail->next = vmodule_list;
+    vmodule_list = head;
+  }
+  inited_vmodule = true;
+}
+
+// This can be called very early, so we use SpinLock and RAW_VLOG here.
+int SetVLOGLevel(const char* module_pattern, int log_level) {
+  int result = FLAGS_v;
+  int const pattern_len = strlen(module_pattern);
+  bool found = false;
+  {
+    MutexLock l(&vmodule_lock);  // protect whole read-modify-write
+    for (const VModuleInfo* info = vmodule_list;
+         info != NULL; info = info->next) {
+      if (info->module_pattern == module_pattern) {
+        if (!found) {
+          result = info->vlog_level;
+          found = true;
+        }
+        info->vlog_level = log_level;
+      } else if (!found  &&
+                 SafeFNMatch_(info->module_pattern.c_str(),
+                              info->module_pattern.size(),
+                              module_pattern, pattern_len)) {
+        result = info->vlog_level;
+        found = true;
+      }
+    }
+    if (!found) {
+      VModuleInfo* info = new VModuleInfo;
+      info->module_pattern = module_pattern;
+      info->vlog_level = log_level;
+      info->next = vmodule_list;
+      vmodule_list = info;
+    }
+  }
+  RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level);
+  return result;
+}
+
+// NOTE: Individual VLOG statements cache the integer log level pointers.
+// NOTE: This function must not allocate memory or require any locks.
+bool InitVLOG3__(int32** site_flag, int32* site_default,
+                 const char* fname, int32 verbose_level) {
+  MutexLock l(&vmodule_lock);
+  bool read_vmodule_flag = inited_vmodule;
+  if (!read_vmodule_flag) {
+    VLOG2Initializer();
+  }
+
+  // protect the errno global in case someone writes:
+  // VLOG(..) << "The last error was " << strerror(errno)
+  int old_errno = errno;
+
+  // site_default normally points to FLAGS_v
+  int32* site_flag_value = site_default;
+
+  // Get basename for file
+  const char* base = strrchr(fname, '/');
+  base = base ? (base+1) : fname;
+  const char* base_end = strchr(base, '.');
+  size_t base_length = base_end ? size_t(base_end - base) : strlen(base);
+
+  // Trim out trailing "-inl" if any
+  if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) {
+    base_length -= 4;
+  }
+
+  // TODO: Trim out _unittest suffix?  Perhaps it is better to have
+  // the extra control and just leave it there.
+
+  // find target in vector of modules, replace site_flag_value with
+  // a module-specific verbose level, if any.
+  for (const VModuleInfo* info = vmodule_list;
+       info != NULL; info = info->next) {
+    if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(),
+                     base, base_length)) {
+      site_flag_value = &info->vlog_level;
+        // value at info->vlog_level is now what controls
+        // the VLOG at the caller site forever
+      break;
+    }
+  }
+
+  // Cache the vlog value pointer if --vmodule flag has been parsed.
+  ANNOTATE_BENIGN_RACE(site_flag,
+                       "*site_flag may be written by several threads,"
+                       " but the value will be the same");
+  if (read_vmodule_flag) *site_flag = site_flag_value;
+
+  // restore the errno in case something recoverable went wrong during
+  // the initialization of the VLOG mechanism (see above note "protect the..")
+  errno = old_errno;
+  return *site_flag_value >= verbose_level;
+}
+
+_END_GOOGLE_NAMESPACE_
diff --git a/third_party/google-glog/src/windows/config.h b/third_party/google-glog/src/windows/config.h
new file mode 100755
index 0000000..2d23fb0
--- /dev/null
+++ b/third_party/google-glog/src/windows/config.h
@@ -0,0 +1,21 @@
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Namespace for Google classes */
+#define GOOGLE_NAMESPACE google
+
+/* Stops putting the code inside the Google namespace */
+#define _END_GOOGLE_NAMESPACE_ }
+
+/* Puts following code inside the Google namespace */
+#define _START_GOOGLE_NAMESPACE_ namespace google {
+
+/* Always the empty-string on non-windows systems. On windows, should be
+   "__declspec(dllexport)". This way, when we compile the dll, we export our
+   functions/classes. It's safe to define this here because config.h is only
+   used internally, to compile the DLL, and every DLL source file #includes
+   "config.h" before anything else. */
+#ifndef GOOGLE_GLOG_DLL_DECL
+# define GOOGLE_GLOG_IS_A_DLL  1   /* not set if you're statically linking */
+# define GOOGLE_GLOG_DLL_DECL  __declspec(dllexport)
+# define GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS  __declspec(dllimport)
+#endif
diff --git a/third_party/google-glog/src/windows/glog/log_severity.h b/third_party/google-glog/src/windows/glog/log_severity.h
new file mode 100644
index 0000000..22a4191
--- /dev/null
+++ b/third_party/google-glog/src/windows/glog/log_severity.h
@@ -0,0 +1,96 @@
+// This file is automatically generated from src/glog/log_severity.h
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef BASE_LOG_SEVERITY_H__
+#define BASE_LOG_SEVERITY_H__
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+#   define GOOGLE_GLOG_DLL_DECL  __declspec(dllimport)
+# else
+#   define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// Variables of type LogSeverity are widely taken to lie in the range
+// [0, NUM_SEVERITIES-1].  Be careful to preserve this assumption if
+// you ever need to change their values or add a new severity.
+typedef int LogSeverity;
+
+const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
+  NUM_SEVERITIES = 4;
+#ifndef GLOG_NO_ABBREVIATED_SEVERITIES
+# ifdef ERROR
+#  error ERROR macro is defined. Define GLOG_NO_ABBREVIATED_SEVERITIES before including logging.h. See the document for detail.
+# endif
+const int INFO = GLOG_INFO, WARNING = GLOG_WARNING,
+  ERROR = GLOG_ERROR, FATAL = GLOG_FATAL;
+#endif
+
+// DFATAL is FATAL in debug mode, ERROR in normal mode
+#ifdef NDEBUG
+#define DFATAL_LEVEL ERROR
+#else
+#define DFATAL_LEVEL FATAL
+#endif
+
+extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES];
+
+// NDEBUG usage helpers related to (RAW_)DCHECK:
+//
+// DEBUG_MODE is for small !NDEBUG uses like
+//   if (DEBUG_MODE) foo.CheckThatFoo();
+// instead of substantially more verbose
+//   #ifndef NDEBUG
+//     foo.CheckThatFoo();
+//   #endif
+//
+// IF_DEBUG_MODE is for small !NDEBUG uses like
+//   IF_DEBUG_MODE( string error; )
+//   DCHECK(Foo(&error)) << error;
+// instead of substantially more verbose
+//   #ifndef NDEBUG
+//     string error;
+//     DCHECK(Foo(&error)) << error;
+//   #endif
+//
+#ifdef NDEBUG
+enum { DEBUG_MODE = 0 };
+#define IF_DEBUG_MODE(x)
+#else
+enum { DEBUG_MODE = 1 };
+#define IF_DEBUG_MODE(x) x
+#endif
+
+#endif  // BASE_LOG_SEVERITY_H__
diff --git a/third_party/google-glog/src/windows/glog/logging.h b/third_party/google-glog/src/windows/glog/logging.h
new file mode 100755
index 0000000..26e080b
--- /dev/null
+++ b/third_party/google-glog/src/windows/glog/logging.h
@@ -0,0 +1,1662 @@
+// This file is automatically generated from src/glog/logging.h.in
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 1999, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney
+//
+// This file contains #include information about logging-related stuff.
+// Pretty much everybody needs to #include this file so that they can
+// log various happenings.
+//
+#ifndef _LOGGING_H_
+#define _LOGGING_H_
+
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <iosfwd>
+#include <ostream>
+#include <sstream>
+#include <string>
+#if 0
+# include <unistd.h>
+#endif
+#include <vector>
+
+#if defined(_MSC_VER)
+#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \
+                                     __pragma(warning(disable:n))
+#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop))
+#else
+#define GLOG_MSVC_PUSH_DISABLE_WARNING(n)
+#define GLOG_MSVC_POP_WARNING()
+#endif
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+#   define GOOGLE_GLOG_DLL_DECL  __declspec(dllimport)
+# else
+#   define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// We care a lot about number of bits things take up.  Unfortunately,
+// systems define their bit-specific ints in a lot of different ways.
+// We use our own way, and have a typedef to get there.
+// Note: these commands below may look like "#if 1" or "#if 0", but
+// that's because they were constructed that way at ./configure time.
+// Look at logging.h.in to see how they're calculated (based on your config).
+#if 0
+#include <stdint.h>             // the normal place uint16_t is defined
+#endif
+#if 0
+#include <sys/types.h>          // the normal place u_int16_t is defined
+#endif
+#if 0
+#include <inttypes.h>           // a third place for uint16_t or u_int16_t
+#endif
+
+#if 0
+#include <gflags/gflags.h>
+#endif
+
+namespace google {
+
+#if 0      // the C99 format
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+#elif 0   // the BSD format
+typedef int32_t int32;
+typedef u_int32_t uint32;
+typedef int64_t int64;
+typedef u_int64_t uint64;
+#elif 1    // the windows (vc7) format
+typedef __int32 int32;
+typedef unsigned __int32 uint32;
+typedef __int64 int64;
+typedef unsigned __int64 uint64;
+#else
+#error Do not know how to define a 32-bit integer quantity on your system
+#endif
+
+}
+
+// The global value of GOOGLE_STRIP_LOG. All the messages logged to
+// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed.
+// If it can be determined at compile time that the message will not be
+// printed, the statement will be compiled out.
+//
+// Example: to strip out all INFO and WARNING messages, use the value
+// of 2 below. To make an exception for WARNING messages from a single
+// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including
+// base/logging.h
+#ifndef GOOGLE_STRIP_LOG
+#define GOOGLE_STRIP_LOG 0
+#endif
+
+// GCC can be told that a certain branch is not likely to be taken (for
+// instance, a CHECK failure), and use that information in static analysis.
+// Giving it this information can help it optimize for the common case in
+// the absence of better information (ie. -fprofile-arcs).
+//
+#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN
+#if 0
+#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0))
+#else
+#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x
+#endif
+#endif
+
+#ifndef GOOGLE_PREDICT_FALSE
+#if 0
+#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
+#else
+#define GOOGLE_PREDICT_FALSE(x) x
+#endif
+#endif
+
+#ifndef GOOGLE_PREDICT_TRUE
+#if 0
+#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
+#else
+#define GOOGLE_PREDICT_TRUE(x) x
+#endif
+#endif
+
+
+// Make a bunch of macros for logging.  The way to log things is to stream
+// things to LOG(<a particular severity level>).  E.g.,
+//
+//   LOG(INFO) << "Found " << num_cookies << " cookies";
+//
+// You can capture log messages in a string, rather than reporting them
+// immediately:
+//
+//   vector<string> errors;
+//   LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num;
+//
+// This pushes back the new error onto 'errors'; if given a NULL pointer,
+// it reports the error via LOG(ERROR).
+//
+// You can also do conditional logging:
+//
+//   LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+// You can also do occasional logging (log every n'th occurrence of an
+// event):
+//
+//   LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
+//
+// The above will cause log messages to be output on the 1st, 11th, 21st, ...
+// times it is executed.  Note that the special google::COUNTER value is used
+// to identify which repetition is happening.
+//
+// You can also do occasional conditional logging (log every n'th
+// occurrence of an event, when condition is satisfied):
+//
+//   LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER
+//                                           << "th big cookie";
+//
+// You can log messages the first N times your code executes a line. E.g.
+//
+//   LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie";
+//
+// Outputs log messages for the first 20 times it is executed.
+//
+// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available.
+// These log to syslog as well as to the normal logs.  If you use these at
+// all, you need to be aware that syslog can drastically reduce performance,
+// especially if it is configured for remote logging!  Don't use these
+// unless you fully understand this and have a concrete need to use them.
+// Even then, try to minimize your use of them.
+//
+// There are also "debug mode" logging macros like the ones above:
+//
+//   DLOG(INFO) << "Found cookies";
+//
+//   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
+//
+//   DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
+//
+// All "debug mode" logging is compiled away to nothing for non-debug mode
+// compiles.
+//
+// We also have
+//
+//   LOG_ASSERT(assertion);
+//   DLOG_ASSERT(assertion);
+//
+// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion;
+//
+// There are "verbose level" logging macros.  They look like
+//
+//   VLOG(1) << "I'm printed when you run the program with --v=1 or more";
+//   VLOG(2) << "I'm printed when you run the program with --v=2 or more";
+//
+// These always log at the INFO log level (when they log at all).
+// The verbose logging can also be turned on module-by-module.  For instance,
+//    --vmodule=mapreduce=2,file=1,gfs*=3 --v=0
+// will cause:
+//   a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc}
+//   b. VLOG(1) and lower messages to be printed from file.{h,cc}
+//   c. VLOG(3) and lower messages to be printed from files prefixed with "gfs"
+//   d. VLOG(0) and lower messages to be printed from elsewhere
+//
+// The wildcarding functionality shown by (c) supports both '*' (match
+// 0 or more characters) and '?' (match any single character) wildcards.
+//
+// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as
+//
+//   if (VLOG_IS_ON(2)) {
+//     // do some logging preparation and logging
+//     // that can't be accomplished with just VLOG(2) << ...;
+//   }
+//
+// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level"
+// condition macros for sample cases, when some extra computation and
+// preparation for logs is not needed.
+//   VLOG_IF(1, (size > 1024))
+//      << "I'm printed when size is more than 1024 and when you run the "
+//         "program with --v=1 or more";
+//   VLOG_EVERY_N(1, 10)
+//      << "I'm printed every 10th occurrence, and when you run the program "
+//         "with --v=1 or more. Present occurence is " << google::COUNTER;
+//   VLOG_IF_EVERY_N(1, (size > 1024), 10)
+//      << "I'm printed on every 10th occurence of case when size is more "
+//         " than 1024, when you run the program with --v=1 or more. ";
+//         "Present occurence is " << google::COUNTER;
+//
+// The supported severity levels for macros that allow you to specify one
+// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL.
+// Note that messages of a given severity are logged not only in the
+// logfile for that severity, but also in all logfiles of lower severity.
+// E.g., a message of severity FATAL will be logged to the logfiles of
+// severity FATAL, ERROR, WARNING, and INFO.
+//
+// There is also the special severity of DFATAL, which logs FATAL in
+// debug mode, ERROR in normal mode.
+//
+// Very important: logging a message at the FATAL severity level causes
+// the program to terminate (after the message is logged).
+//
+// Unless otherwise specified, logs will be written to the filename
+// "<program name>.<hostname>.<user name>.log.<severity level>.", followed
+// by the date, time, and pid (you can't prevent the date, time, and pid
+// from being in the filename).
+//
+// The logging code takes two flags:
+//     --v=#           set the verbose level
+//     --logtostderr   log all the messages to stderr instead of to logfiles
+
+// LOG LINE PREFIX FORMAT
+//
+// Log lines have this form:
+//
+//     Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
+//
+// where the fields are defined as follows:
+//
+//   L                A single character, representing the log level
+//                    (eg 'I' for INFO)
+//   mm               The month (zero padded; ie May is '05')
+//   dd               The day (zero padded)
+//   hh:mm:ss.uuuuuu  Time in hours, minutes and fractional seconds
+//   threadid         The space-padded thread ID as returned by GetTID()
+//                    (this matches the PID on Linux)
+//   file             The file name
+//   line             The line number
+//   msg              The user-supplied message
+//
+// Example:
+//
+//   I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog
+//   I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395
+//
+// NOTE: although the microseconds are useful for comparing events on
+// a single machine, clocks on different machines may not be well
+// synchronized.  Hence, use caution when comparing the low bits of
+// timestamps from different machines.
+
+#ifndef DECLARE_VARIABLE
+#define MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#define DECLARE_VARIABLE(type, shorttype, name, tn)                     \
+  namespace fL##shorttype {                                             \
+    extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name;                      \
+  }                                                                     \
+  using fL##shorttype::FLAGS_##name
+
+// bool specialization
+#define DECLARE_bool(name) \
+  DECLARE_VARIABLE(bool, B, name, bool)
+
+// int32 specialization
+#define DECLARE_int32(name) \
+  DECLARE_VARIABLE(google::int32, I, name, int32)
+
+// Special case for string, because we have to specify the namespace
+// std::string, which doesn't play nicely with our FLAG__namespace hackery.
+#define DECLARE_string(name)                                            \
+  namespace fLS {                                                       \
+    extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name;              \
+  }                                                                     \
+  using fLS::FLAGS_##name
+#endif
+
+// Set whether log messages go to stderr instead of logfiles
+DECLARE_bool(logtostderr);
+
+// Set whether log messages go to stderr in addition to logfiles.
+DECLARE_bool(alsologtostderr);
+
+// Set color messages logged to stderr (if supported by terminal).
+DECLARE_bool(colorlogtostderr);
+
+// Log messages at a level >= this flag are automatically sent to
+// stderr in addition to log files.
+DECLARE_int32(stderrthreshold);
+
+// Set whether the log prefix should be prepended to each line of output.
+DECLARE_bool(log_prefix);
+
+// Log messages at a level <= this flag are buffered.
+// Log messages at a higher level are flushed immediately.
+DECLARE_int32(logbuflevel);
+
+// Sets the maximum number of seconds which logs may be buffered for.
+DECLARE_int32(logbufsecs);
+
+// Log suppression level: messages logged at a lower level than this
+// are suppressed.
+DECLARE_int32(minloglevel);
+
+// If specified, logfiles are written into this directory instead of the
+// default logging directory.
+DECLARE_string(log_dir);
+
+// Set the log file mode.
+DECLARE_int32(logfile_mode);
+
+// Sets the path of the directory into which to put additional links
+// to the log files.
+DECLARE_string(log_link);
+
+DECLARE_int32(v);  // in vlog_is_on.cc
+
+// Sets the maximum log file size (in MB).
+DECLARE_int32(max_log_size);
+
+// Sets whether to avoid logging to the disk if the disk is full.
+DECLARE_bool(stop_logging_if_full_disk);
+
+#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS
+#undef DECLARE_VARIABLE
+#undef DECLARE_bool
+#undef DECLARE_int32
+#undef DECLARE_string
+#endif
+
+// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for
+// security reasons. See LOG(severtiy) below.
+
+// A few definitions of macros that don't generate much code.  Since
+// LOG(INFO) and its ilk are used all over our code, it's
+// better to have compact code for these operations.
+
+#if GOOGLE_STRIP_LOG == 0
+#define COMPACT_GOOGLE_LOG_INFO google::LogMessage( \
+      __FILE__, __LINE__)
+#define LOG_TO_STRING_INFO(message) google::LogMessage( \
+      __FILE__, __LINE__, google::GLOG_INFO, message)
+#else
+#define COMPACT_GOOGLE_LOG_INFO google::NullStream()
+#define LOG_TO_STRING_INFO(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 1
+#define COMPACT_GOOGLE_LOG_WARNING google::LogMessage( \
+      __FILE__, __LINE__, google::GLOG_WARNING)
+#define LOG_TO_STRING_WARNING(message) google::LogMessage( \
+      __FILE__, __LINE__, google::GLOG_WARNING, message)
+#else
+#define COMPACT_GOOGLE_LOG_WARNING google::NullStream()
+#define LOG_TO_STRING_WARNING(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 2
+#define COMPACT_GOOGLE_LOG_ERROR google::LogMessage( \
+      __FILE__, __LINE__, google::GLOG_ERROR)
+#define LOG_TO_STRING_ERROR(message) google::LogMessage( \
+      __FILE__, __LINE__, google::GLOG_ERROR, message)
+#else
+#define COMPACT_GOOGLE_LOG_ERROR google::NullStream()
+#define LOG_TO_STRING_ERROR(message) google::NullStream()
+#endif
+
+#if GOOGLE_STRIP_LOG <= 3
+#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal( \
+      __FILE__, __LINE__)
+#define LOG_TO_STRING_FATAL(message) google::LogMessage( \
+      __FILE__, __LINE__, google::GLOG_FATAL, message)
+#else
+#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal()
+#define LOG_TO_STRING_FATAL(message) google::NullStreamFatal()
+#endif
+
+#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
+#define DCHECK_IS_ON() 0
+#else
+#define DCHECK_IS_ON() 1
+#endif
+
+// For DFATAL, we want to use LogMessage (as opposed to
+// LogMessageFatal), to be consistent with the original behavior.
+#if !DCHECK_IS_ON()
+#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR
+#elif GOOGLE_STRIP_LOG <= 3
+#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage( \
+      __FILE__, __LINE__, google::GLOG_FATAL)
+#else
+#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal()
+#endif
+
+#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, counter, &google::LogMessage::SendToLog)
+#define SYSLOG_INFO(counter) \
+  google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO, counter, \
+  &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_WARNING(counter)  \
+  google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, counter, \
+  &google::LogMessage::SendToLog)
+#define SYSLOG_WARNING(counter)  \
+  google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING, counter, \
+  &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_ERROR(counter)  \
+  google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, counter, \
+  &google::LogMessage::SendToLog)
+#define SYSLOG_ERROR(counter)  \
+  google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, counter, \
+  &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_FATAL(counter) \
+  google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, counter, \
+  &google::LogMessage::SendToLog)
+#define SYSLOG_FATAL(counter) \
+  google::LogMessage(__FILE__, __LINE__, google::GLOG_FATAL, counter, \
+  &google::LogMessage::SendToSyslogAndLog)
+#define GOOGLE_LOG_DFATAL(counter) \
+  google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \
+  &google::LogMessage::SendToLog)
+#define SYSLOG_DFATAL(counter) \
+  google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \
+  &google::LogMessage::SendToSyslogAndLog)
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__)
+// A very useful logging macro to log windows errors:
+#define LOG_SYSRESULT(result) \
+  if (FAILED(HRESULT_FROM_WIN32(result))) { \
+    LPSTR message = NULL; \
+    LPSTR msg = reinterpret_cast<LPSTR>(&message); \
+    DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
+                         FORMAT_MESSAGE_FROM_SYSTEM, \
+                         0, result, 0, msg, 100, NULL); \
+    if (message_length > 0) { \
+      google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \
+          &google::LogMessage::SendToLog).stream() \
+          << reinterpret_cast<const char*>(message); \
+      LocalFree(message); \
+    } \
+  }
+#endif
+
+// We use the preprocessor's merging operator, "##", so that, e.g.,
+// LOG(INFO) becomes the token GOOGLE_LOG_INFO.  There's some funny
+// subtle difference between ostream member streaming functions (e.g.,
+// ostream::operator<<(int) and ostream non-member streaming functions
+// (e.g., ::operator<<(ostream&, string&): it turns out that it's
+// impossible to stream something like a string directly to an unnamed
+// ostream. We employ a neat hack by calling the stream() member
+// function of LogMessage which seems to avoid the problem.
+#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
+#define SYSLOG(severity) SYSLOG_ ## severity(0).stream()
+
+namespace google {
+
+// They need the definitions of integer types.
+#include "glog/log_severity.h"
+#include "glog/vlog_is_on.h"
+
+// Initialize google's logging library. You will see the program name
+// specified by argv0 in log outputs.
+GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0);
+
+// Shutdown google's logging library.
+GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging();
+
+// Install a function which will be called after LOG(FATAL).
+GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)());
+
+class LogSink;  // defined below
+
+// If a non-NULL sink pointer is given, we push this message to that sink.
+// For LOG_TO_SINK we then do normal LOG(severity) logging as well.
+// This is useful for capturing messages and passing/storing them
+// somewhere more specific than the global log of the process.
+// Argument types:
+//   LogSink* sink;
+//   LogSeverity severity;
+// The cast is to disambiguate NULL arguments.
+#define LOG_TO_SINK(sink, severity) \
+  google::LogMessage(                                    \
+      __FILE__, __LINE__,                                               \
+      google::GLOG_ ## severity,                         \
+      static_cast<google::LogSink*>(sink), true).stream()
+#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity)                  \
+  google::LogMessage(                                    \
+      __FILE__, __LINE__,                                               \
+      google::GLOG_ ## severity,                         \
+      static_cast<google::LogSink*>(sink), false).stream()
+
+// If a non-NULL string pointer is given, we write this message to that string.
+// We then do normal LOG(severity) logging as well.
+// This is useful for capturing messages and storing them somewhere more
+// specific than the global log of the process.
+// Argument types:
+//   string* message;
+//   LogSeverity severity;
+// The cast is to disambiguate NULL arguments.
+// NOTE: LOG(severity) expands to LogMessage().stream() for the specified
+// severity.
+#define LOG_TO_STRING(severity, message) \
+  LOG_TO_STRING_##severity(static_cast<string*>(message)).stream()
+
+// If a non-NULL pointer is given, we push the message onto the end
+// of a vector of strings; otherwise, we report it with LOG(severity).
+// This is handy for capturing messages and perhaps passing them back
+// to the caller, rather than reporting them immediately.
+// Argument types:
+//   LogSeverity severity;
+//   vector<string> *outvec;
+// The cast is to disambiguate NULL arguments.
+#define LOG_STRING(severity, outvec) \
+  LOG_TO_STRING_##severity(static_cast<std::vector<std::string>*>(outvec)).stream()
+
+#define LOG_IF(severity, condition) \
+  !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+#define SYSLOG_IF(severity, condition) \
+  !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity)
+
+#define LOG_ASSERT(condition)  \
+  LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
+#define SYSLOG_ASSERT(condition) \
+  SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition
+
+// CHECK dies with a fatal error if condition is not true.  It is *not*
+// controlled by DCHECK_IS_ON(), so the check will be executed regardless of
+// compilation mode.  Therefore, it is safe to do things like:
+//    CHECK(fp->Write(x) == 4)
+#define CHECK(condition)  \
+      LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
+             << "Check failed: " #condition " "
+
+// A container for a string pointer which can be evaluated to a bool -
+// true iff the pointer is NULL.
+struct CheckOpString {
+  CheckOpString(std::string* str) : str_(str) { }
+  // No destructor: if str_ is non-NULL, we're about to LOG(FATAL),
+  // so there's no point in cleaning up str_.
+  operator bool() const {
+    return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL);
+  }
+  std::string* str_;
+};
+
+// Function is overloaded for integral types to allow static const
+// integrals declared in classes and not defined to be used as arguments to
+// CHECK* macros. It's not encouraged though.
+template <class T>
+inline const T&       GetReferenceableValue(const T&           t) { return t; }
+inline char           GetReferenceableValue(char               t) { return t; }
+inline unsigned char  GetReferenceableValue(unsigned char      t) { return t; }
+inline signed char    GetReferenceableValue(signed char        t) { return t; }
+inline short          GetReferenceableValue(short              t) { return t; }
+inline unsigned short GetReferenceableValue(unsigned short     t) { return t; }
+inline int            GetReferenceableValue(int                t) { return t; }
+inline unsigned int   GetReferenceableValue(unsigned int       t) { return t; }
+inline long           GetReferenceableValue(long               t) { return t; }
+inline unsigned long  GetReferenceableValue(unsigned long      t) { return t; }
+inline long long      GetReferenceableValue(long long          t) { return t; }
+inline unsigned long long GetReferenceableValue(unsigned long long t) {
+  return t;
+}
+
+// This is a dummy class to define the following operator.
+struct DummyClassToDefineOperator {};
+
+}
+
+// Define global operator<< to declare using ::operator<<.
+// This declaration will allow use to use CHECK macros for user
+// defined classes which have operator<< (e.g., stl_logging.h).
+inline std::ostream& operator<<(
+    std::ostream& out, const google::DummyClassToDefineOperator&) {
+  return out;
+}
+
+namespace google {
+
+// This formats a value for a failing CHECK_XX statement.  Ordinarily,
+// it uses the definition for operator<<, with a few special cases below.
+template <typename T>
+inline void MakeCheckOpValueString(std::ostream* os, const T& v) {
+  (*os) << v;
+}
+
+// Overrides for char types provide readable values for unprintable
+// characters.
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const char& v);
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const signed char& v);
+template <> GOOGLE_GLOG_DLL_DECL
+void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);
+
+// Build the error message string. Specify no inlining for code size.
+template <typename T1, typename T2>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext)
+    ;
+
+namespace base {
+namespace internal {
+
+// If "s" is less than base_logging::INFO, returns base_logging::INFO.
+// If "s" is greater than base_logging::FATAL, returns
+// base_logging::ERROR.  Otherwise, returns "s".
+LogSeverity NormalizeSeverity(LogSeverity s);
+
+}  // namespace internal
+
+// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX
+// statement.  See MakeCheckOpString for sample usage.  Other
+// approaches were considered: use of a template method (e.g.,
+// base::BuildCheckOpString(exprtext, base::Print<T1>, &v1,
+// base::Print<T2>, &v2), however this approach has complications
+// related to volatile arguments and function-pointer arguments).
+class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder {
+ public:
+  // Inserts "exprtext" and " (" to the stream.
+  explicit CheckOpMessageBuilder(const char *exprtext);
+  // Deletes "stream_".
+  ~CheckOpMessageBuilder();
+  // For inserting the first variable.
+  std::ostream* ForVar1() { return stream_; }
+  // For inserting the second variable (adds an intermediate " vs. ").
+  std::ostream* ForVar2();
+  // Get the result (inserts the closing ")").
+  std::string* NewString();
+
+ private:
+  std::ostringstream *stream_;
+};
+
+}  // namespace base
+
+template <typename T1, typename T2>
+std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) {
+  base::CheckOpMessageBuilder comb(exprtext);
+  MakeCheckOpValueString(comb.ForVar1(), v1);
+  MakeCheckOpValueString(comb.ForVar2(), v2);
+  return comb.NewString();
+}
+
+// Helper functions for CHECK_OP macro.
+// The (int, int) specialization works around the issue that the compiler
+// will not instantiate the template version of the function on values of
+// unnamed enum type - see comment below.
+#define DEFINE_CHECK_OP_IMPL(name, op) \
+  template <typename T1, typename T2> \
+  inline std::string* name##Impl(const T1& v1, const T2& v2,    \
+                            const char* exprtext) { \
+    if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \
+    else return MakeCheckOpString(v1, v2, exprtext); \
+  } \
+  inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \
+    return name##Impl<int, int>(v1, v2, exprtext); \
+  }
+
+// We use the full name Check_EQ, Check_NE, etc. in case the file including
+// base/logging.h provides its own #defines for the simpler names EQ, NE, etc.
+// This happens if, for example, those are used as token names in a
+// yacc grammar.
+DEFINE_CHECK_OP_IMPL(Check_EQ, ==)  // Compilation error with CHECK_EQ(NULL, x)?
+DEFINE_CHECK_OP_IMPL(Check_NE, !=)  // Use CHECK(x == NULL) instead.
+DEFINE_CHECK_OP_IMPL(Check_LE, <=)
+DEFINE_CHECK_OP_IMPL(Check_LT, < )
+DEFINE_CHECK_OP_IMPL(Check_GE, >=)
+DEFINE_CHECK_OP_IMPL(Check_GT, > )
+#undef DEFINE_CHECK_OP_IMPL
+
+// Helper macro for binary operators.
+// Don't use this macro directly in your code, use CHECK_EQ et al below.
+
+#if defined(STATIC_ANALYSIS)
+// Only for static analysis tool to know that it is equivalent to assert
+#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2))
+#elif DCHECK_IS_ON()
+// In debug mode, avoid constructing CheckOpStrings if possible,
+// to reduce the overhead of CHECK statments by 2x.
+// Real DCHECK-heavy tests have seen 1.5x speedups.
+
+// The meaning of "string" might be different between now and
+// when this macro gets invoked (e.g., if someone is experimenting
+// with other string implementations that get defined after this
+// file is included).  Save the current meaning now and use it
+// in the macro.
+typedef std::string _Check_string;
+#define CHECK_OP_LOG(name, op, val1, val2, log)                         \
+  while (google::_Check_string* _result =                \
+         google::Check##name##Impl(                      \
+             google::GetReferenceableValue(val1),        \
+             google::GetReferenceableValue(val2),        \
+             #val1 " " #op " " #val2))                                  \
+    log(__FILE__, __LINE__,                                             \
+        google::CheckOpString(_result)).stream()
+#else
+// In optimized mode, use CheckOpString to hint to compiler that
+// the while condition is unlikely.
+#define CHECK_OP_LOG(name, op, val1, val2, log)                         \
+  while (google::CheckOpString _result =                 \
+         google::Check##name##Impl(                      \
+             google::GetReferenceableValue(val1),        \
+             google::GetReferenceableValue(val2),        \
+             #val1 " " #op " " #val2))                                  \
+    log(__FILE__, __LINE__, _result).stream()
+#endif  // STATIC_ANALYSIS, DCHECK_IS_ON()
+
+#if GOOGLE_STRIP_LOG <= 3
+#define CHECK_OP(name, op, val1, val2) \
+  CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal)
+#else
+#define CHECK_OP(name, op, val1, val2) \
+  CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal)
+#endif // STRIP_LOG <= 3
+
+// Equality/Inequality checks - compare two values, and log a FATAL message
+// including the two values when the result is not as expected.  The values
+// must have operator<<(ostream, ...) defined.
+//
+// You may append to the error message like so:
+//   CHECK_NE(1, 2) << ": The world must be ending!";
+//
+// We are very careful to ensure that each argument is evaluated exactly
+// once, and that anything which is legal to pass as a function argument is
+// legal here.  In particular, the arguments may be temporary expressions
+// which will end up being destroyed at the end of the apparent statement,
+// for example:
+//   CHECK_EQ(string("abc")[1], 'b');
+//
+// WARNING: These don't compile correctly if one of the arguments is a pointer
+// and the other is NULL. To work around this, simply static_cast NULL to the
+// type of the desired pointer.
+
+#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2)
+#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2)
+#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2)
+#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2)
+#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2)
+#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2)
+
+// Check that the input is non NULL.  This very useful in constructor
+// initializer lists.
+
+#define CHECK_NOTNULL(val) \
+  google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val))
+
+// Helper functions for string comparisons.
+// To avoid bloat, the definitions are in logging.cc.
+#define DECLARE_CHECK_STROP_IMPL(func, expected) \
+  GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \
+      const char* s1, const char* s2, const char* names);
+DECLARE_CHECK_STROP_IMPL(strcmp, true)
+DECLARE_CHECK_STROP_IMPL(strcmp, false)
+DECLARE_CHECK_STROP_IMPL(strcasecmp, true)
+DECLARE_CHECK_STROP_IMPL(strcasecmp, false)
+#undef DECLARE_CHECK_STROP_IMPL
+
+// Helper macro for string comparisons.
+// Don't use this macro directly in your code, use CHECK_STREQ et al below.
+#define CHECK_STROP(func, op, expected, s1, s2) \
+  while (google::CheckOpString _result = \
+         google::Check##func##expected##Impl((s1), (s2), \
+                                     #s1 " " #op " " #s2)) \
+    LOG(FATAL) << *_result.str_
+
+
+// String (char*) equality/inequality checks.
+// CASE versions are case-insensitive.
+//
+// Note that "s1" and "s2" may be temporary strings which are destroyed
+// by the compiler at the end of the current "full expression"
+// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())).
+
+#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2)
+#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2)
+#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2)
+#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2)
+
+#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0])))
+#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0])))
+
+#define CHECK_DOUBLE_EQ(val1, val2)              \
+  do {                                           \
+    CHECK_LE((val1), (val2)+0.000000000000001L); \
+    CHECK_GE((val1), (val2)-0.000000000000001L); \
+  } while (0)
+
+#define CHECK_NEAR(val1, val2, margin)           \
+  do {                                           \
+    CHECK_LE((val1), (val2)+(margin));           \
+    CHECK_GE((val1), (val2)-(margin));           \
+  } while (0)
+
+// perror()..googly style!
+//
+// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and
+// CHECK equivalents with the addition that they postpend a description
+// of the current state of errno to their output lines.
+
+#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream()
+
+#define GOOGLE_PLOG(severity, counter)  \
+  google::ErrnoLogMessage( \
+      __FILE__, __LINE__, google::GLOG_ ## severity, counter, \
+      &google::LogMessage::SendToLog)
+
+#define PLOG_IF(severity, condition) \
+  !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity)
+
+// A CHECK() macro that postpends errno if the condition is false. E.g.
+//
+// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... }
+#define PCHECK(condition)  \
+      PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \
+              << "Check failed: " #condition " "
+
+// A CHECK() macro that lets you assert the success of a function that
+// returns -1 and sets errno in case of an error. E.g.
+//
+// CHECK_ERR(mkdir(path, 0700));
+//
+// or
+//
+// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename;
+#define CHECK_ERR(invocation)                                          \
+PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1))    \
+        << #invocation
+
+// Use macro expansion to create, for each use of LOG_EVERY_N(), static
+// variables with the __LINE__ expansion as part of the variable name.
+#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line)
+#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line
+
+#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__)
+#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__)
+
+#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
+  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+  ++LOG_OCCURRENCES; \
+  if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
+  if (LOG_OCCURRENCES_MOD_N == 1) \
+    google::LogMessage( \
+        __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \
+        &what_to_do).stream()
+
+#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
+  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+  ++LOG_OCCURRENCES; \
+  if (condition && \
+      ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \
+    google::LogMessage( \
+        __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \
+                 &what_to_do).stream()
+
+#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
+  static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
+  ++LOG_OCCURRENCES; \
+  if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \
+  if (LOG_OCCURRENCES_MOD_N == 1) \
+    google::ErrnoLogMessage( \
+        __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \
+        &what_to_do).stream()
+
+#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
+  static int LOG_OCCURRENCES = 0; \
+  if (LOG_OCCURRENCES <= n) \
+    ++LOG_OCCURRENCES; \
+  if (LOG_OCCURRENCES <= n) \
+    google::LogMessage( \
+        __FILE__, __LINE__, google::GLOG_ ## severity, LOG_OCCURRENCES, \
+        &what_to_do).stream()
+
+namespace glog_internal_namespace_ {
+template <bool>
+struct CompileAssert {
+};
+struct CrashReason;
+
+// Returns true if FailureSignalHandler is installed.
+bool IsFailureSignalHandlerInstalled();
+}  // namespace glog_internal_namespace_
+
+#define LOG_EVERY_N(severity, n)                                        \
+  SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog)
+
+#define SYSLOG_EVERY_N(severity, n) \
+  SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog)
+
+#define PLOG_EVERY_N(severity, n) \
+  SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog)
+
+#define LOG_FIRST_N(severity, n) \
+  SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog)
+
+#define LOG_IF_EVERY_N(severity, condition, n) \
+  SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog)
+
+// We want the special COUNTER value available for LOG_EVERY_X()'ed messages
+enum PRIVATE_Counter {COUNTER};
+
+#ifdef GLOG_NO_ABBREVIATED_SEVERITIES
+// wingdi.h defines ERROR to be 0. When we call LOG(ERROR), it gets
+// substituted with 0, and it expands to COMPACT_GOOGLE_LOG_0. To allow us
+// to keep using this syntax, we define this macro to do the same thing
+// as COMPACT_GOOGLE_LOG_ERROR.
+#define COMPACT_GOOGLE_LOG_0 COMPACT_GOOGLE_LOG_ERROR
+#define SYSLOG_0 SYSLOG_ERROR
+#define LOG_TO_STRING_0 LOG_TO_STRING_ERROR
+// Needed for LOG_IS_ON(ERROR).
+const LogSeverity GLOG_0 = GLOG_ERROR;
+#else
+// Users may include windows.h after logging.h without
+// GLOG_NO_ABBREVIATED_SEVERITIES nor WIN32_LEAN_AND_MEAN.
+// For this case, we cannot detect if ERROR is defined before users
+// actually use ERROR. Let's make an undefined symbol to warn users.
+# define GLOG_ERROR_MSG ERROR_macro_is_defined_Define_GLOG_NO_ABBREVIATED_SEVERITIES_before_including_logging_h_See_the_document_for_detail
+# define COMPACT_GOOGLE_LOG_0 GLOG_ERROR_MSG
+# define SYSLOG_0 GLOG_ERROR_MSG
+# define LOG_TO_STRING_0 GLOG_ERROR_MSG
+# define GLOG_0 GLOG_ERROR_MSG
+#endif
+
+// Plus some debug-logging macros that get compiled to nothing for production
+
+#if DCHECK_IS_ON()
+
+#define DLOG(severity) LOG(severity)
+#define DVLOG(verboselevel) VLOG(verboselevel)
+#define DLOG_IF(severity, condition) LOG_IF(severity, condition)
+#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n)
+#define DLOG_IF_EVERY_N(severity, condition, n) \
+  LOG_IF_EVERY_N(severity, condition, n)
+#define DLOG_ASSERT(condition) LOG_ASSERT(condition)
+
+// debug-only checking.  executed if DCHECK_IS_ON().
+#define DCHECK(condition) CHECK(condition)
+#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
+#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
+#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
+#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
+#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
+#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
+#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val)
+#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2)
+#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2)
+#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2)
+#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2)
+
+#else  // !DCHECK_IS_ON()
+
+#define DLOG(severity) \
+  true ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DVLOG(verboselevel) \
+  (true || !VLOG_IS_ON(verboselevel)) ?\
+    (void) 0 : google::LogMessageVoidify() & LOG(INFO)
+
+#define DLOG_IF(severity, condition) \
+  (true || !(condition)) ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_EVERY_N(severity, n) \
+  true ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_IF_EVERY_N(severity, condition, n) \
+  (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity)
+
+#define DLOG_ASSERT(condition) \
+  true ? (void) 0 : LOG_ASSERT(condition)
+
+// MSVC warning C4127: conditional expression is constant
+#define DCHECK(condition) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK(condition)
+
+#define DCHECK_EQ(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2)
+
+#define DCHECK_NE(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2)
+
+#define DCHECK_LE(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2)
+
+#define DCHECK_LT(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2)
+
+#define DCHECK_GE(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2)
+
+#define DCHECK_GT(val1, val2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2)
+
+// You may see warnings in release mode if you don't use the return
+// value of DCHECK_NOTNULL. Please just use DCHECK for such cases.
+#define DCHECK_NOTNULL(val) (val)
+
+#define DCHECK_STREQ(str1, str2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2)
+
+#define DCHECK_STRCASEEQ(str1, str2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2)
+
+#define DCHECK_STRNE(str1, str2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2)
+
+#define DCHECK_STRCASENE(str1, str2) \
+  GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \
+  while (false) \
+    GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2)
+
+#endif  // DCHECK_IS_ON()
+
+// Log only in verbose mode.
+
+#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel))
+
+#define VLOG_IF(verboselevel, condition) \
+  LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel))
+
+#define VLOG_EVERY_N(verboselevel, n) \
+  LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n)
+
+#define VLOG_IF_EVERY_N(verboselevel, condition, n) \
+  LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n)
+
+namespace base_logging {
+
+// LogMessage::LogStream is a std::ostream backed by this streambuf.
+// This class ignores overflow and leaves two bytes at the end of the
+// buffer to allow for a '\n' and '\0'.
+class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf {
+ public:
+  // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\n'.
+  LogStreamBuf(char *buf, int len) {
+    setp(buf, buf + len - 2);
+  }
+
+  // Resets the buffer. Useful if we reuse it by means of TLS.
+  void reset() {
+     setp(pbase(), epptr());
+  }
+
+  // This effectively ignores overflow.
+  virtual int_type overflow(int_type ch) {
+    return ch;
+  }
+
+  // Legacy public ostrstream method.
+  size_t pcount() const { return pptr() - pbase(); }
+  char* pbase() const { return std::streambuf::pbase(); }
+};
+
+}  // namespace base_logging
+
+//
+// This class more or less represents a particular log message.  You
+// create an instance of LogMessage and then stream stuff to it.
+// When you finish streaming to it, ~LogMessage is called and the
+// full message gets streamed to the appropriate destination.
+//
+// You shouldn't actually use LogMessage's constructor to log things,
+// though.  You should use the LOG() macro (and variants thereof)
+// above.
+class GOOGLE_GLOG_DLL_DECL LogMessage {
+public:
+  enum {
+    // Passing kNoLogPrefix for the line number disables the
+    // log-message prefix. Useful for using the LogMessage
+    // infrastructure as a printing utility. See also the --log_prefix
+    // flag for controlling the log-message prefix on an
+    // application-wide basis.
+    kNoLogPrefix = -1
+  };
+
+  // LogStream inherit from non-DLL-exported class (std::ostrstream)
+  // and VC++ produces a warning for this situation.
+  // However, MSDN says "C4275 can be ignored in Microsoft Visual C++
+  // 2005 if you are deriving from a type in the Standard C++ Library"
+  // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx
+  // Let's just ignore the warning.
+GLOG_MSVC_PUSH_DISABLE_WARNING(4275)
+  class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream {
+GLOG_MSVC_POP_WARNING()
+  public:
+    LogStream(char *buf, int len, int ctr)
+        : std::ostream(NULL),
+          streambuf_(buf, len),
+          ctr_(ctr),
+          self_(this) {
+      rdbuf(&streambuf_);
+    }
+
+    int ctr() const { return ctr_; }
+    void set_ctr(int ctr) { ctr_ = ctr; }
+    LogStream* self() const { return self_; }
+
+    // Legacy std::streambuf methods.
+    size_t pcount() const { return streambuf_.pcount(); }
+    char* pbase() const { return streambuf_.pbase(); }
+    char* str() const { return pbase(); }
+    void reset() { streambuf_.reset(); }
+
+  private:
+    LogStream(const LogStream&);
+    LogStream& operator=(const LogStream&);
+    base_logging::LogStreamBuf streambuf_;
+    int ctr_;  // Counter hack (for the LOG_EVERY_X() macro)
+    LogStream *self_;  // Consistency check hack
+  };
+
+public:
+  // icc 8 requires this typedef to avoid an internal compiler error.
+  typedef void (LogMessage::*SendMethod)();
+
+  LogMessage(const char* file, int line, LogSeverity severity, int ctr,
+             SendMethod send_method);
+
+  // Two special constructors that generate reduced amounts of code at
+  // LOG call sites for common cases.
+
+  // Used for LOG(INFO): Implied are:
+  // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog.
+  //
+  // Using this constructor instead of the more complex constructor above
+  // saves 19 bytes per call site.
+  LogMessage(const char* file, int line);
+
+  // Used for LOG(severity) where severity != INFO.  Implied
+  // are: ctr = 0, send_method = &LogMessage::SendToLog
+  //
+  // Using this constructor instead of the more complex constructor above
+  // saves 17 bytes per call site.
+  LogMessage(const char* file, int line, LogSeverity severity);
+
+  // Constructor to log this message to a specified sink (if not NULL).
+  // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if
+  // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise.
+  LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink,
+             bool also_send_to_log);
+
+  // Constructor where we also give a vector<string> pointer
+  // for storing the messages (if the pointer is not NULL).
+  // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog.
+  LogMessage(const char* file, int line, LogSeverity severity,
+             std::vector<std::string>* outvec);
+
+  // Constructor where we also give a string pointer for storing the
+  // message (if the pointer is not NULL).  Implied are: ctr = 0,
+  // send_method = &LogMessage::WriteToStringAndLog.
+  LogMessage(const char* file, int line, LogSeverity severity,
+             std::string* message);
+
+  // A special constructor used for check failures
+  LogMessage(const char* file, int line, const CheckOpString& result);
+
+  ~LogMessage();
+
+  // Flush a buffered message to the sink set in the constructor.  Always
+  // called by the destructor, it may also be called from elsewhere if
+  // needed.  Only the first call is actioned; any later ones are ignored.
+  void Flush();
+
+  // An arbitrary limit on the length of a single log message.  This
+  // is so that streaming can be done more efficiently.
+  static const size_t kMaxLogMessageLen;
+
+  // Theses should not be called directly outside of logging.*,
+  // only passed as SendMethod arguments to other LogMessage methods:
+  void SendToLog();  // Actually dispatch to the logs
+  void SendToSyslogAndLog();  // Actually dispatch to syslog and the logs
+
+  // Call abort() or similar to perform LOG(FATAL) crash.
+  static void __declspec(noreturn) Fail();
+
+  std::ostream& stream();
+
+  int preserved_errno() const;
+
+  // Must be called without the log_mutex held.  (L < log_mutex)
+  static int64 num_messages(int severity);
+
+  struct LogMessageData;
+
+private:
+  // Fully internal SendMethod cases:
+  void SendToSinkAndLog();  // Send to sink if provided and dispatch to the logs
+  void SendToSink();  // Send to sink if provided, do nothing otherwise.
+
+  // Write to string if provided and dispatch to the logs.
+  void WriteToStringAndLog();
+
+  void SaveOrSendToLog();  // Save to stringvec if provided, else to logs
+
+  void Init(const char* file, int line, LogSeverity severity,
+            void (LogMessage::*send_method)());
+
+  // Used to fill in crash information during LOG(FATAL) failures.
+  void RecordCrashReason(glog_internal_namespace_::CrashReason* reason);
+
+  // Counts of messages sent at each priority:
+  static int64 num_messages_[NUM_SEVERITIES];  // under log_mutex
+
+  // We keep the data in a separate struct so that each instance of
+  // LogMessage uses less stack space.
+  LogMessageData* allocated_;
+  LogMessageData* data_;
+
+  friend class LogDestination;
+
+  LogMessage(const LogMessage&);
+  void operator=(const LogMessage&);
+};
+
+// This class happens to be thread-hostile because all instances share
+// a single data buffer, but since it can only be created just before
+// the process dies, we don't worry so much.
+class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage {
+ public:
+  LogMessageFatal(const char* file, int line);
+  LogMessageFatal(const char* file, int line, const CheckOpString& result);
+  __declspec(noreturn) ~LogMessageFatal();
+};
+
+// A non-macro interface to the log facility; (useful
+// when the logging level is not a compile-time constant).
+inline void LogAtLevel(int const severity, std::string const &msg) {
+  LogMessage(__FILE__, __LINE__, severity).stream() << msg;
+}
+
+// A macro alternative of LogAtLevel. New code may want to use this
+// version since there are two advantages: 1. this version outputs the
+// file name and the line number where this macro is put like other
+// LOG macros, 2. this macro can be used as C++ stream.
+#define LOG_AT_LEVEL(severity) google::LogMessage(__FILE__, __LINE__, severity).stream()
+
+// Check if it's compiled in C++11 mode.
+//
+// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least
+// gcc-4.7 and clang-3.1 (2011-12-13).  __cplusplus was defined to 1
+// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is
+// defined according to the language version in effect thereafter.
+// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite
+// reasonably good C++11 support, so we set LANG_CXX for it and
+// newer versions (_MSC_VER >= 1900).
+#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
+     (defined(_MSC_VER) && _MSC_VER >= 1900))
+// Helper for CHECK_NOTNULL().
+//
+// In C++11, all cases can be handled by a single function. Since the value
+// category of the argument is preserved (also for rvalue references),
+// member initializer lists like the one below will compile correctly:
+//
+//   Foo()
+//     : x_(CHECK_NOTNULL(MethodReturningUniquePtr())) {}
+template <typename T>
+T CheckNotNull(const char* file, int line, const char* names, T&& t) {
+ if (t == nullptr) {
+   LogMessageFatal(file, line, new std::string(names));
+ }
+ return std::forward<T>(t);
+}
+
+#else
+
+// A small helper for CHECK_NOTNULL().
+template <typename T>
+T* CheckNotNull(const char *file, int line, const char *names, T* t) {
+  if (t == NULL) {
+    LogMessageFatal(file, line, new std::string(names));
+  }
+  return t;
+}
+#endif
+
+// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This
+// only works if ostream is a LogStream. If the ostream is not a
+// LogStream you'll get an assert saying as much at runtime.
+GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os,
+                                              const PRIVATE_Counter&);
+
+
+// Derived class for PLOG*() above.
+class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage {
+ public:
+
+  ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr,
+                  void (LogMessage::*send_method)());
+
+  // Postpends ": strerror(errno) [errno]".
+  ~ErrnoLogMessage();
+
+ private:
+  ErrnoLogMessage(const ErrnoLogMessage&);
+  void operator=(const ErrnoLogMessage&);
+};
+
+
+// This class is used to explicitly ignore values in the conditional
+// logging macros.  This avoids compiler warnings like "value computed
+// is not used" and "statement has no effect".
+
+class GOOGLE_GLOG_DLL_DECL LogMessageVoidify {
+ public:
+  LogMessageVoidify() { }
+  // This has to be an operator with a precedence lower than << but
+  // higher than ?:
+  void operator&(std::ostream&) { }
+};
+
+
+// Flushes all log files that contains messages that are at least of
+// the specified severity level.  Thread-safe.
+GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity);
+
+// Flushes all log files that contains messages that are at least of
+// the specified severity level. Thread-hostile because it ignores
+// locking -- used for catastrophic failures.
+GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity);
+
+//
+// Set the destination to which a particular severity level of log
+// messages is sent.  If base_filename is "", it means "don't log this
+// severity".  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity,
+                                            const char* base_filename);
+
+//
+// Set the basename of the symlink to the latest log file at a given
+// severity.  If symlink_basename is empty, do not make a symlink.  If
+// you don't call this function, the symlink basename is the
+// invocation name of the program.  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity,
+                                        const char* symlink_basename);
+
+//
+// Used to send logs to some other kind of destination
+// Users should subclass LogSink and override send to do whatever they want.
+// Implementations must be thread-safe because a shared instance will
+// be called from whichever thread ran the LOG(XXX) line.
+class GOOGLE_GLOG_DLL_DECL LogSink {
+ public:
+  virtual ~LogSink();
+
+  // Sink's logging logic (message_len is such as to exclude '\n' at the end).
+  // This method can't use LOG() or CHECK() as logging system mutex(s) are held
+  // during this call.
+  virtual void send(LogSeverity severity, const char* full_filename,
+                    const char* base_filename, int line,
+                    const struct ::tm* tm_time,
+                    const char* message, size_t message_len) = 0;
+
+  // Redefine this to implement waiting for
+  // the sink's logging logic to complete.
+  // It will be called after each send() returns,
+  // but before that LogMessage exits or crashes.
+  // By default this function does nothing.
+  // Using this function one can implement complex logic for send()
+  // that itself involves logging; and do all this w/o causing deadlocks and
+  // inconsistent rearrangement of log messages.
+  // E.g. if a LogSink has thread-specific actions, the send() method
+  // can simply add the message to a queue and wake up another thread that
+  // handles real logging while itself making some LOG() calls;
+  // WaitTillSent() can be implemented to wait for that logic to complete.
+  // See our unittest for an example.
+  virtual void WaitTillSent();
+
+  // Returns the normal text output of the log message.
+  // Can be useful to implement send().
+  static std::string ToString(LogSeverity severity, const char* file, int line,
+                              const struct ::tm* tm_time,
+                              const char* message, size_t message_len);
+};
+
+// Add or remove a LogSink as a consumer of logging data.  Thread-safe.
+GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination);
+GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination);
+
+//
+// Specify an "extension" added to the filename specified via
+// SetLogDestination.  This applies to all severity levels.  It's
+// often used to append the port we're listening on to the logfile
+// name.  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension(
+    const char* filename_extension);
+
+//
+// Make it so that all log messages of at least a particular severity
+// are logged to stderr (in addition to logging to the usual log
+// file(s)).  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity);
+
+//
+// Make it so that all log messages go only to stderr.  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void LogToStderr();
+
+//
+// Make it so that all log messages of at least a particular severity are
+// logged via email to a list of addresses (in addition to logging to the
+// usual log file(s)).  The list of addresses is just a string containing
+// the email addresses to send to (separated by spaces, say).  Thread-safe.
+//
+GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity,
+                                          const char* addresses);
+
+// A simple function that sends email. dest is a commma-separated
+// list of addressess.  Thread-safe.
+GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest,
+                                    const char *subject, const char *body);
+
+GOOGLE_GLOG_DLL_DECL const std::vector<std::string>& GetLoggingDirectories();
+
+// For tests only:  Clear the internal [cached] list of logging directories to
+// force a refresh the next time GetLoggingDirectories is called.
+// Thread-hostile.
+void TestOnly_ClearLoggingDirectoriesList();
+
+// Returns a set of existing temporary directories, which will be a
+// subset of the directories returned by GetLogginDirectories().
+// Thread-safe.
+GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories(
+    std::vector<std::string>* list);
+
+// Print any fatal message again -- useful to call from signal handler
+// so that the last thing in the output is the fatal message.
+// Thread-hostile, but a race is unlikely.
+GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage();
+
+// Truncate a log file that may be the append-only output of multiple
+// processes and hence can't simply be renamed/reopened (typically a
+// stdout/stderr).  If the file "path" is > "limit" bytes, copy the
+// last "keep" bytes to offset 0 and truncate the rest. Since we could
+// be racing with other writers, this approach has the potential to
+// lose very small amounts of data. For security, only follow symlinks
+// if the path is /proc/self/fd/*
+GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path,
+                                          int64 limit, int64 keep);
+
+// Truncate stdout and stderr if they are over the value specified by
+// --max_log_size; keep the final 1MB.  This function has the same
+// race condition as TruncateLogFile.
+GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr();
+
+// Return the string representation of the provided LogSeverity level.
+// Thread-safe.
+GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity);
+
+// ---------------------------------------------------------------------
+// Implementation details that are not useful to most clients
+// ---------------------------------------------------------------------
+
+// A Logger is the interface used by logging modules to emit entries
+// to a log.  A typical implementation will dump formatted data to a
+// sequence of files.  We also provide interfaces that will forward
+// the data to another thread so that the invoker never blocks.
+// Implementations should be thread-safe since the logging system
+// will write to them from multiple threads.
+
+namespace base {
+
+class GOOGLE_GLOG_DLL_DECL Logger {
+ public:
+  virtual ~Logger();
+
+  // Writes "message[0,message_len-1]" corresponding to an event that
+  // occurred at "timestamp".  If "force_flush" is true, the log file
+  // is flushed immediately.
+  //
+  // The input message has already been formatted as deemed
+  // appropriate by the higher level logging facility.  For example,
+  // textual log messages already contain timestamps, and the
+  // file:linenumber header.
+  virtual void Write(bool force_flush,
+                     time_t timestamp,
+                     const char* message,
+                     int message_len) = 0;
+
+  // Flush any buffered messages
+  virtual void Flush() = 0;
+
+  // Get the current LOG file size.
+  // The returned value is approximate since some
+  // logged data may not have been flushed to disk yet.
+  virtual uint32 LogSize() = 0;
+};
+
+// Get the logger for the specified severity level.  The logger
+// remains the property of the logging module and should not be
+// deleted by the caller.  Thread-safe.
+extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level);
+
+// Set the logger for the specified severity level.  The logger
+// becomes the property of the logging module and should not
+// be deleted by the caller.  Thread-safe.
+extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger);
+
+}
+
+// glibc has traditionally implemented two incompatible versions of
+// strerror_r(). There is a poorly defined convention for picking the
+// version that we want, but it is not clear whether it even works with
+// all versions of glibc.
+// So, instead, we provide this wrapper that automatically detects the
+// version that is in use, and then implements POSIX semantics.
+// N.B. In addition to what POSIX says, we also guarantee that "buf" will
+// be set to an empty string, if this function failed. This means, in most
+// cases, you do not need to check the error code and you can directly
+// use the value of "buf". It will never have an undefined value.
+// DEPRECATED: Use StrError(int) instead.
+GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len);
+
+// A thread-safe replacement for strerror(). Returns a string describing the
+// given POSIX error code.
+GOOGLE_GLOG_DLL_DECL std::string StrError(int err);
+
+// A class for which we define operator<<, which does nothing.
+class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream {
+ public:
+  // Initialize the LogStream so the messages can be written somewhere
+  // (they'll never be actually displayed). This will be needed if a
+  // NullStream& is implicitly converted to LogStream&, in which case
+  // the overloaded NullStream::operator<< will not be invoked.
+  NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { }
+  NullStream(const char* /*file*/, int /*line*/,
+             const CheckOpString& /*result*/) :
+      LogMessage::LogStream(message_buffer_, 1, 0) { }
+  NullStream &stream() { return *this; }
+ private:
+  // A very short buffer for messages (which we discard anyway). This
+  // will be needed if NullStream& converted to LogStream& (e.g. as a
+  // result of a conditional expression).
+  char message_buffer_[2];
+};
+
+// Do nothing. This operator is inline, allowing the message to be
+// compiled away. The message will not be compiled away if we do
+// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when
+// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly
+// converted to LogStream and the message will be computed and then
+// quietly discarded.
+template<class T>
+inline NullStream& operator<<(NullStream &str, const T &) { return str; }
+
+// Similar to NullStream, but aborts the program (without stack
+// trace), like LogMessageFatal.
+class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream {
+ public:
+  NullStreamFatal() { }
+  NullStreamFatal(const char* file, int line, const CheckOpString& result) :
+      NullStream(file, line, result) { }
+  __declspec(noreturn) ~NullStreamFatal() throw () { _exit(1); }
+};
+
+// Install a signal handler that will dump signal information and a stack
+// trace when the program crashes on certain signals.  We'll install the
+// signal handler for the following signals.
+//
+// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM.
+//
+// By default, the signal handler will write the failure dump to the
+// standard error.  You can customize the destination by installing your
+// own writer function by InstallFailureWriter() below.
+//
+// Note on threading:
+//
+// The function should be called before threads are created, if you want
+// to use the failure signal handler for all threads.  The stack trace
+// will be shown only for the thread that receives the signal.  In other
+// words, stack traces of other threads won't be shown.
+GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler();
+
+// Installs a function that is used for writing the failure dump.  "data"
+// is the pointer to the beginning of a message to be written, and "size"
+// is the size of the message.  You should not expect the data is
+// terminated with '\0'.
+GOOGLE_GLOG_DLL_DECL void InstallFailureWriter(
+    void (*writer)(const char* data, int size));
+
+}
+
+#endif // _LOGGING_H_
diff --git a/third_party/google-glog/src/windows/glog/raw_logging.h b/third_party/google-glog/src/windows/glog/raw_logging.h
new file mode 100755
index 0000000..4757a71
--- /dev/null
+++ b/third_party/google-glog/src/windows/glog/raw_logging.h
@@ -0,0 +1,189 @@
+// This file is automatically generated from src/glog/raw_logging.h.in
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Maxim Lifantsev
+//
+// Thread-safe logging routines that do not allocate any memory or
+// acquire any locks, and can therefore be used by low-level memory
+// allocation and synchronization code.
+
+#ifndef BASE_RAW_LOGGING_H_
+#define BASE_RAW_LOGGING_H_
+
+#include <time.h>
+
+namespace google {
+
+#include "glog/log_severity.h"
+#include "glog/vlog_is_on.h"
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+#   define GOOGLE_GLOG_DLL_DECL  __declspec(dllimport)
+# else
+#   define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+// This is similar to LOG(severity) << format... and VLOG(level) << format..,
+// but
+// * it is to be used ONLY by low-level modules that can't use normal LOG()
+// * it is desiged to be a low-level logger that does not allocate any
+//   memory and does not need any locks, hence:
+// * it logs straight and ONLY to STDERR w/o buffering
+// * it uses an explicit format and arguments list
+// * it will silently chop off really long message strings
+// Usage example:
+//   RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
+//   RAW_VLOG(3, "status is %i", status);
+// These will print an almost standard log lines like this to stderr only:
+//   E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
+//   I0821 211317 file.cc:142] RAW: status is 20
+#define RAW_LOG(severity, ...) \
+  do { \
+    switch (google::GLOG_ ## severity) {  \
+      case 0: \
+        RAW_LOG_INFO(__VA_ARGS__); \
+        break; \
+      case 1: \
+        RAW_LOG_WARNING(__VA_ARGS__); \
+        break; \
+      case 2: \
+        RAW_LOG_ERROR(__VA_ARGS__); \
+        break; \
+      case 3: \
+        RAW_LOG_FATAL(__VA_ARGS__); \
+        break; \
+      default: \
+        break; \
+    } \
+  } while (0)
+
+// The following STRIP_LOG testing is performed in the header file so that it's
+// possible to completely compile out the logging code and the log messages.
+#if STRIP_LOG == 0
+#define RAW_VLOG(verboselevel, ...) \
+  do { \
+    if (VLOG_IS_ON(verboselevel)) { \
+      RAW_LOG_INFO(__VA_ARGS__); \
+    } \
+  } while (0)
+#else
+#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG == 0
+
+#if STRIP_LOG == 0
+#define RAW_LOG_INFO(...) google::RawLog__(google::GLOG_INFO, \
+                                   __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG == 0
+
+#if STRIP_LOG <= 1
+#define RAW_LOG_WARNING(...) google::RawLog__(google::GLOG_WARNING,   \
+                                      __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG <= 1
+
+#if STRIP_LOG <= 2
+#define RAW_LOG_ERROR(...) google::RawLog__(google::GLOG_ERROR,       \
+                                    __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
+#endif // STRIP_LOG <= 2
+
+#if STRIP_LOG <= 3
+#define RAW_LOG_FATAL(...) google::RawLog__(google::GLOG_FATAL,       \
+                                    __FILE__, __LINE__, __VA_ARGS__)
+#else
+#define RAW_LOG_FATAL(...) \
+  do { \
+    google::RawLogStub__(0, __VA_ARGS__);        \
+    exit(1); \
+  } while (0)
+#endif // STRIP_LOG <= 3
+
+// Similar to CHECK(condition) << message,
+// but for low-level modules: we use only RAW_LOG that does not allocate memory.
+// We do not want to provide args list here to encourage this usage:
+//   if (!cond)  RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
+// so that the args are not computed when not needed.
+#define RAW_CHECK(condition, message)                                   \
+  do {                                                                  \
+    if (!(condition)) {                                                 \
+      RAW_LOG(FATAL, "Check %s failed: %s", #condition, message);       \
+    }                                                                   \
+  } while (0)
+
+// Debug versions of RAW_LOG and RAW_CHECK
+#ifndef NDEBUG
+
+#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
+#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
+
+#else  // NDEBUG
+
+#define RAW_DLOG(severity, ...)                                 \
+  while (false)                                                 \
+    RAW_LOG(severity, __VA_ARGS__)
+#define RAW_DCHECK(condition, message) \
+  while (false) \
+    RAW_CHECK(condition, message)
+
+#endif  // NDEBUG
+
+// Stub log function used to work around for unused variable warnings when
+// building with STRIP_LOG > 0.
+static inline void RawLogStub__(int /* ignored */, ...) {
+}
+
+// Helper function to implement RAW_LOG and RAW_VLOG
+// Logs format... at "severity" level, reporting it
+// as called from file:line.
+// This does not allocate memory or acquire locks.
+GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity,
+                                   const char* file,
+                                   int line,
+                                   const char* format, ...)
+   ;
+
+// Hack to propagate time information into this module so that
+// this module does not have to directly call localtime_r(),
+// which could allocate memory.
+GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs);
+
+}
+
+#endif  // BASE_RAW_LOGGING_H_
diff --git a/third_party/google-glog/src/windows/glog/stl_logging.h b/third_party/google-glog/src/windows/glog/stl_logging.h
new file mode 100755
index 0000000..a97a908
--- /dev/null
+++ b/third_party/google-glog/src/windows/glog/stl_logging.h
@@ -0,0 +1,224 @@
+// This file is automatically generated from src/glog/stl_logging.h.in
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 2003, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Stream output operators for STL containers; to be used for logging *only*.
+// Inclusion of this file lets you do:
+//
+// list<string> x;
+// LOG(INFO) << "data: " << x;
+// vector<int> v1, v2;
+// CHECK_EQ(v1, v2);
+//
+// If you want to use this header file with hash_compare maps or slist, you
+// need to define macros before including this file:
+//
+// - GLOG_STL_LOGGING_FOR_UNORDERED     - <unordered_map> and <unordered_set>
+// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)>
+// - GLOG_STL_LOGGING_FOR_EXT_HASH      - <ext/hash_(map|set)>
+// - GLOG_STL_LOGGING_FOR_EXT_SLIST     - <ext/slist>
+//
+
+#ifndef UTIL_GTL_STL_LOGGING_INL_H_
+#define UTIL_GTL_STL_LOGGING_INL_H_
+
+#if !1
+# error We do not support stl_logging for this compiler
+#endif
+
+#include <deque>
+#include <list>
+#include <map>
+#include <ostream>
+#include <set>
+#include <utility>
+#include <vector>
+
+#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
+# include <unordered_map>
+# include <unordered_set>
+#endif
+
+#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
+# include <tr1/unordered_map>
+# include <tr1/unordered_set>
+#endif
+
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+# include <ext/hash_set>
+# include <ext/hash_map>
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
+# include <ext/slist>
+#endif
+
+// Forward declare these two, and define them after all the container streams
+// operators so that we can recurse from pair -> container -> container -> pair
+// properly.
+template<class First, class Second>
+std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p);
+
+namespace google {
+
+template<class Iter>
+void PrintSequence(std::ostream& out, Iter begin, Iter end);
+
+}
+
+#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
+template<class T1, class T2> \
+inline std::ostream& operator<<(std::ostream& out, \
+                                const Sequence<T1, T2>& seq) { \
+  google::PrintSequence(out, seq.begin(), seq.end()); \
+  return out; \
+}
+
+OUTPUT_TWO_ARG_CONTAINER(std::vector)
+OUTPUT_TWO_ARG_CONTAINER(std::deque)
+OUTPUT_TWO_ARG_CONTAINER(std::list)
+#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
+OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist)
+#endif
+
+#undef OUTPUT_TWO_ARG_CONTAINER
+
+#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \
+template<class T1, class T2, class T3> \
+inline std::ostream& operator<<(std::ostream& out, \
+                                const Sequence<T1, T2, T3>& seq) { \
+  google::PrintSequence(out, seq.begin(), seq.end()); \
+  return out; \
+}
+
+OUTPUT_THREE_ARG_CONTAINER(std::set)
+OUTPUT_THREE_ARG_CONTAINER(std::multiset)
+
+#undef OUTPUT_THREE_ARG_CONTAINER
+
+#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \
+template<class T1, class T2, class T3, class T4> \
+inline std::ostream& operator<<(std::ostream& out, \
+                                const Sequence<T1, T2, T3, T4>& seq) { \
+  google::PrintSequence(out, seq.begin(), seq.end()); \
+  return out; \
+}
+
+OUTPUT_FOUR_ARG_CONTAINER(std::map)
+OUTPUT_FOUR_ARG_CONTAINER(std::multimap)
+#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
+OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
+OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
+OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set)
+OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset)
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set)
+OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset)
+#endif
+
+#undef OUTPUT_FOUR_ARG_CONTAINER
+
+#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \
+template<class T1, class T2, class T3, class T4, class T5> \
+inline std::ostream& operator<<(std::ostream& out, \
+                                const Sequence<T1, T2, T3, T4, T5>& seq) { \
+  google::PrintSequence(out, seq.begin(), seq.end()); \
+  return out; \
+}
+
+#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
+OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
+OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
+OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map)
+OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap)
+#endif
+#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
+OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map)
+OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap)
+#endif
+
+#undef OUTPUT_FIVE_ARG_CONTAINER
+
+template<class First, class Second>
+inline std::ostream& operator<<(std::ostream& out,
+                                const std::pair<First, Second>& p) {
+  out << '(' << p.first << ", " << p.second << ')';
+  return out;
+}
+
+namespace google {
+
+template<class Iter>
+inline void PrintSequence(std::ostream& out, Iter begin, Iter end) {
+  // Output at most 100 elements -- appropriate if used for logging.
+  for (int i = 0; begin != end && i < 100; ++i, ++begin) {
+    if (i > 0) out << ' ';
+    out << *begin;
+  }
+  if (begin != end) {
+    out << " ...";
+  }
+}
+
+}
+
+// Note that this is technically undefined behavior! We are adding things into
+// the std namespace for a reason though -- we are providing new operations on
+// types which are themselves defined with this namespace. Without this, these
+// operator overloads cannot be found via ADL. If these definitions are not
+// found via ADL, they must be #included before they're used, which requires
+// this header to be included before apparently independent other headers.
+//
+// For example, base/logging.h defines various template functions to implement
+// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails.
+// It does so via the function template MakeCheckOpValueString:
+//   template<class T>
+//   void MakeCheckOpValueString(strstream* ss, const T& v) {
+//     (*ss) << v;
+//   }
+// Because 'glog/logging.h' is included before 'glog/stl_logging.h',
+// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only
+// find these operator definitions via ADL.
+//
+// Even this solution has problems -- it may pull unintended operators into the
+// namespace as well, allowing them to also be found via ADL, and creating code
+// that only works with a particular order of includes. Long term, we need to
+// move all of the *definitions* into namespace std, bet we need to ensure no
+// one references them first. This lets us take that step. We cannot define them
+// in both because that would create ambiguous overloads when both are found.
+namespace std { using ::operator<<; }
+
+#endif  // UTIL_GTL_STL_LOGGING_INL_H_
diff --git a/third_party/google-glog/src/windows/glog/vlog_is_on.h b/third_party/google-glog/src/windows/glog/vlog_is_on.h
new file mode 100755
index 0000000..409a401
--- /dev/null
+++ b/third_party/google-glog/src/windows/glog/vlog_is_on.h
@@ -0,0 +1,133 @@
+// This file is automatically generated from src/glog/vlog_is_on.h.in
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+
+// Copyright (c) 1999, 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Ray Sidney and many others
+//
+// Defines the VLOG_IS_ON macro that controls the variable-verbosity
+// conditional logging.
+//
+// It's used by VLOG and VLOG_IF in logging.h
+// and by RAW_VLOG in raw_logging.h to trigger the logging.
+//
+// It can also be used directly e.g. like this:
+//   if (VLOG_IS_ON(2)) {
+//     // do some logging preparation and logging
+//     // that can't be accomplished e.g. via just VLOG(2) << ...;
+//   }
+//
+// The truth value that VLOG_IS_ON(level) returns is determined by 
+// the three verbosity level flags:
+//   --v=<n>  Gives the default maximal active V-logging level;
+//            0 is the default.
+//            Normally positive values are used for V-logging levels.
+//   --vmodule=<str>  Gives the per-module maximal V-logging levels to override
+//                    the value given by --v.
+//                    E.g. "my_module=2,foo*=3" would change the logging level
+//                    for all code in source files "my_module.*" and "foo*.*"
+//                    ("-inl" suffixes are also disregarded for this matching).
+//
+// SetVLOGLevel helper function is provided to do limited dynamic control over
+// V-logging by overriding the per-module settings given via --vmodule flag.
+//
+// CAVEAT: --vmodule functionality is not available in non gcc compilers.
+//
+
+#ifndef BASE_VLOG_IS_ON_H_
+#define BASE_VLOG_IS_ON_H_
+
+#include "glog/log_severity.h"
+
+// Annoying stuff for windows -- makes sure clients can import these functions
+#ifndef GOOGLE_GLOG_DLL_DECL
+# if defined(_WIN32) && !defined(__CYGWIN__)
+#   define GOOGLE_GLOG_DLL_DECL  __declspec(dllimport)
+# else
+#   define GOOGLE_GLOG_DLL_DECL
+# endif
+#endif
+
+#if defined(__GNUC__)
+// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
+// (Normally) the first time every VLOG_IS_ON(n) site is hit,
+// we determine what variable will dynamically control logging at this site:
+// it's either FLAGS_v or an appropriate internal variable
+// matching the current source file that represents results of
+// parsing of --vmodule flag and/or SetVLOGLevel calls.
+#define VLOG_IS_ON(verboselevel)                                \
+  __extension__  \
+  ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized;           \
+     google::int32 verbose_level__ = (verboselevel);                    \
+     (*vlocal__ >= verbose_level__) &&                          \
+     ((vlocal__ != &google::kLogSiteUninitialized) ||                   \
+      (google::InitVLOG3__(&vlocal__, &FLAGS_v,                         \
+                   __FILE__, verbose_level__))); })
+#else
+// GNU extensions not available, so we do not support --vmodule.
+// Dynamic value of FLAGS_v always controls the logging level.
+#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
+#endif
+
+// Set VLOG(_IS_ON) level for module_pattern to log_level.
+// This lets us dynamically control what is normally set by the --vmodule flag.
+// Returns the level that previously applied to module_pattern.
+// NOTE: To change the log level for VLOG(_IS_ON) sites
+//	 that have already executed after/during InitGoogleLogging,
+//	 one needs to supply the exact --vmodule pattern that applied to them.
+//       (If no --vmodule pattern applied to them
+//       the value of FLAGS_v will continue to control them.)
+extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,
+                                             int log_level);
+
+// Various declarations needed for VLOG_IS_ON above: =========================
+
+// Special value used to indicate that a VLOG_IS_ON site has not been
+// initialized.  We make this a large value, so the common-case check
+// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition
+// passes in such cases and InitVLOG3__ is then triggered.
+extern google::int32 kLogSiteUninitialized;
+
+// Helper routine which determines the logging info for a particalur VLOG site.
+//   site_flag     is the address of the site-local pointer to the controlling
+//                 verbosity level
+//   site_default  is the default to use for *site_flag
+//   fname         is the current source file name
+//   verbose_level is the argument to VLOG_IS_ON
+// We will return the return value for VLOG_IS_ON
+// and if possible set *site_flag appropriately.
+extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
+    google::int32** site_flag,
+    google::int32* site_default,
+    const char* fname,
+    google::int32 verbose_level);
+
+#endif  // BASE_VLOG_IS_ON_H_
diff --git a/third_party/google-glog/src/windows/port.cc b/third_party/google-glog/src/windows/port.cc
new file mode 100755
index 0000000..19bda36
--- /dev/null
+++ b/third_party/google-glog/src/windows/port.cc
@@ -0,0 +1,65 @@
+/* Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ * Copied from google-perftools and modified by Shinichiro Hamaji
+ */
+
+#ifndef _WIN32
+# error You should only be including windows/port.cc in a windows environment!
+#endif
+
+#include "config.h"
+#include <stdarg.h>    // for va_list, va_start, va_end
+#include "port.h"
+
+// These call the windows _vsnprintf, but always NUL-terminate.
+int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
+  if (size == 0)        // not even room for a \0?
+    return -1;          // not what C99 says to do, but what windows does
+  str[size-1] = '\0';
+  return _vsnprintf(str, size-1, format, ap);
+}
+
+#ifndef HAVE_LOCALTIME_R
+struct tm* localtime_r(const time_t* timep, struct tm* result) {
+  localtime_s(result, timep);
+  return result;
+}
+#endif // not HAVE_LOCALTIME_R
+#ifndef HAVE_SNPRINTF
+int snprintf(char *str, size_t size, const char *format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  const int r = vsnprintf(str, size, format, ap);
+  va_end(ap);
+  return r;
+}
+#endif
diff --git a/third_party/google-glog/src/windows/port.h b/third_party/google-glog/src/windows/port.h
new file mode 100755
index 0000000..7b4b9c8
--- /dev/null
+++ b/third_party/google-glog/src/windows/port.h
@@ -0,0 +1,174 @@
+/* Copyright (c) 2008, Google Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ * Copied from google-perftools and modified by Shinichiro Hamaji
+ *
+ * These are some portability typedefs and defines to make it a bit
+ * easier to compile this code under VC++.
+ *
+ * Several of these are taken from glib:
+ *    http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
+ */
+
+#ifndef CTEMPLATE_WINDOWS_PORT_H_
+#define CTEMPLATE_WINDOWS_PORT_H_
+
+#include "config.h"
+
+#ifdef _WIN32
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN  /* We always want minimal includes */
+#endif
+
+#include <windows.h>
+#include <winsock.h>         /* for gethostname */
+#include <io.h>              /* because we so often use open/close/etc */
+#include <direct.h>          /* for _getcwd() */
+#include <process.h>         /* for _getpid() */
+#include <stdio.h>           /* read in vsnprintf decl. before redifining it */
+#include <stdarg.h>          /* template_dictionary.cc uses va_copy */
+#include <string.h>          /* for _strnicmp(), strerror_s() */
+#include <time.h>            /* for localtime_s() */
+/* Note: the C++ #includes are all together at the bottom.  This file is
+ * used by both C and C++ code, so we put all the C++ together.
+ */
+
+#ifdef _MSC_VER
+
+/* 4244: otherwise we get problems when substracting two size_t's to an int
+ * 4251: it's complaining about a private struct I've chosen not to dllexport
+ * 4355: we use this in a constructor, but we do it safely
+ * 4715: for some reason VC++ stopped realizing you can't return after abort()
+ * 4800: we know we're casting ints/char*'s to bools, and we're ok with that
+ * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror()
+ * 4312: Converting uint32_t to a pointer when testing %p
+ * 4267: also subtracting two size_t to int
+ * 4722: Destructor never returns due to abort()
+ */
+#pragma warning(disable:4244 4251 4355 4715 4800 4996 4267 4312 4722)
+
+/* file I/O */
+#define PATH_MAX 1024
+#define access  _access
+#define getcwd  _getcwd
+#define open    _open
+#define read    _read
+#define write   _write
+#define lseek   _lseek
+#define close   _close
+#define popen   _popen
+#define pclose  _pclose
+#define R_OK    04           /* read-only (for access()) */
+#define S_ISDIR(m)  (((m) & _S_IFMT) == _S_IFDIR)
+
+#define O_WRONLY _O_WRONLY
+#define O_CREAT _O_CREAT
+#define O_EXCL _O_EXCL
+
+#ifndef __MINGW32__
+enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
+#endif
+#define S_IRUSR S_IREAD
+#define S_IWUSR S_IWRITE
+
+/* Not quite as lightweight as a hard-link, but more than good enough for us. */
+#define link(oldpath, newpath)  CopyFileA(oldpath, newpath, false)
+
+#define strcasecmp   _stricmp
+#define strncasecmp  _strnicmp
+
+/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */
+/* VC11 provides std::hash */
+#if defined(_MSC_VER) && (_MSC_VER < 1700)
+#define hash  hash_compare
+#endif
+
+/* Sleep is in ms, on windows */
+#define sleep(secs)  Sleep((secs) * 1000)
+
+/* We can't just use _vsnprintf and _snprintf as drop-in-replacements,
+ * because they don't always NUL-terminate. :-(  We also can't use the
+ * name vsnprintf, since windows defines that (but not snprintf (!)).
+ */
+#ifndef HAVE_SNPRINTF
+extern int GOOGLE_GLOG_DLL_DECL snprintf(char *str, size_t size,
+                                       const char *format, ...);
+#endif
+extern int GOOGLE_GLOG_DLL_DECL safe_vsnprintf(char *str, size_t size,
+                          const char *format, va_list ap);
+#define vsnprintf(str, size, format, ap)  safe_vsnprintf(str, size, format, ap)
+#ifndef va_copy
+#define va_copy(dst, src)  (dst) = (src)
+#endif
+
+/* Windows doesn't support specifying the number of buckets as a
+ * hash_map constructor arg, so we leave this blank.
+ */
+#define CTEMPLATE_SMALL_HASHTABLE
+
+#define DEFAULT_TEMPLATE_ROOTDIR  ".."
+
+// ----------------------------------- SYSTEM/PROCESS
+typedef int pid_t;
+#define getpid  _getpid
+
+#endif  // _MSC_VER
+
+// ----------------------------------- THREADS
+#if defined(HAVE_PTHREAD)
+# include <pthread.h>
+#else // no PTHREAD
+typedef DWORD pthread_t;
+typedef DWORD pthread_key_t;
+typedef LONG pthread_once_t;
+enum { PTHREAD_ONCE_INIT = 0 };   // important that this be 0! for SpinLock
+#define pthread_self  GetCurrentThreadId
+#define pthread_equal(pthread_t_1, pthread_t_2)  ((pthread_t_1)==(pthread_t_2))
+#endif // HAVE_PTHREAD
+
+#ifndef HAVE_LOCALTIME_R
+extern GOOGLE_GLOG_DLL_DECL struct tm* localtime_r(const time_t* timep, struct tm* result);
+#endif // not HAVE_LOCALTIME_R
+
+inline char* strerror_r(int errnum, char* buf, size_t buflen) {
+  strerror_s(buf, buflen, errnum);
+  return buf;
+}
+
+#ifndef __cplusplus
+/* I don't see how to get inlining for C code in MSVC.  Ah well. */
+#define inline
+#endif
+
+#endif  /* _WIN32 */
+
+#endif  /* CTEMPLATE_WINDOWS_PORT_H_ */
diff --git a/third_party/google-glog/src/windows/preprocess.sh b/third_party/google-glog/src/windows/preprocess.sh
new file mode 100755
index 0000000..c35e929
--- /dev/null
+++ b/third_party/google-glog/src/windows/preprocess.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+# Copyright (c) 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# ---
+# Author: Craig Silverstein
+# Copied from google-perftools and modified by Shinichiro Hamaji
+#
+# This script is meant to be run at distribution-generation time, for
+# instance by autogen.sh.  It does some of the work configure would
+# normally do, for windows systems.  In particular, it expands all the
+# @...@ variables found in .in files, and puts them here, in the windows
+# directory.
+#
+# This script should be run before any new release.
+
+if [ -z "$1" ]; then
+   echo "USAGE: $0 <src/ directory>"
+   exit 1
+fi
+
+DLLDEF_MACRO_NAME="GLOG_DLL_DECL"
+
+# The text we put in every .h files we create.  As a courtesy, we'll
+# include a helpful comment for windows users as to how to use
+# GLOG_DLL_DECL.  Apparently sed expands \n into a newline.  Good!
+DLLDEF_DEFINES="\
+// NOTE: if you are statically linking the template library into your binary\n\
+// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\
+// as a compiler flag in your project file to turn off the dllimports.\n\
+#ifndef $DLLDEF_MACRO_NAME\n\
+# define $DLLDEF_MACRO_NAME  __declspec(dllimport)\n\
+#endif"
+
+# Read all the windows config info into variables
+# In order for the 'set' to take, this requires putting all in a subshell.
+(
+  while read define varname value; do
+    [ "$define" != "#define" ] && continue
+    eval "$varname='$value'"
+  done
+
+  # Process all the .in files in the "glog" subdirectory
+  mkdir -p "$1/windows/glog"
+  for file in `echo "$1"/glog/*.in`; do
+     echo "Processing $file"
+     outfile="$1/windows/glog/`basename $file .in`"
+
+     echo "\
+// This file is automatically generated from $file
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+" > "$outfile"
+     # Besides replacing @...@, we also need to turn on dllimport
+     # We also need to replace hash by hash_compare (annoying we hard-code :-( )
+     sed -e "s!@ac_windows_dllexport@!$DLLDEF_MACRO_NAME!g" \
+         -e "s!@ac_windows_dllexport_defines@!$DLLDEF_DEFINES!g" \
+         -e "s!@ac_cv_cxx_hash_map@!$HASH_MAP_H!g" \
+         -e "s!@ac_cv_cxx_hash_namespace@!$HASH_NAMESPACE!g" \
+         -e "s!@ac_cv_cxx_hash_set@!$HASH_SET_H!g" \
+         -e "s!@ac_cv_have_stdint_h@!0!g" \
+         -e "s!@ac_cv_have_systypes_h@!0!g" \
+         -e "s!@ac_cv_have_inttypes_h@!0!g" \
+         -e "s!@ac_cv_have_unistd_h@!0!g" \
+         -e "s!@ac_cv_have_uint16_t@!0!g" \
+         -e "s!@ac_cv_have_u_int16_t@!0!g" \
+         -e "s!@ac_cv_have___uint16@!1!g" \
+         -e "s!@ac_cv_have_libgflags@!0!g" \
+         -e "s!@ac_cv_have___builtin_expect@!0!g" \
+         -e "s!@ac_cv_cxx_using_operator@!1!g" \
+         -e "s!@ac_cv___attribute___noreturn@!__declspec(noreturn)!g" \
+         -e "s!@ac_cv___attribute___noinline@!!g" \
+         -e "s!@ac_cv___attribute___printf_4_5@!!g" \
+         -e "s!@ac_google_attribute@!${HAVE___ATTRIBUTE__:-0}!g" \
+         -e "s!@ac_google_end_namespace@!$_END_GOOGLE_NAMESPACE_!g" \
+         -e "s!@ac_google_namespace@!$GOOGLE_NAMESPACE!g" \
+         -e "s!@ac_google_start_namespace@!$_START_GOOGLE_NAMESPACE_!g" \
+         -e "s!@ac_htmlparser_namespace@!$HTMLPARSER_NAMESPACE!g" \
+         -e "s!\\bhash\\b!hash_compare!g" \
+         "$file" >> "$outfile"
+  done
+) < "$1/windows/config.h"
+
+# log_severity.h isn't a .in file.
+echo "\
+// This file is automatically generated from $1/glog/log_severity.h
+// using src/windows/preprocess.sh.
+// DO NOT EDIT!
+" > "$1/windows/glog/log_severity.h"
+cat "$1/glog/log_severity.h" >> "$1/windows/glog/log_severity.h"
+
+echo "DONE"
diff --git a/third_party/google-glog/toolchains/.gitignore b/third_party/google-glog/toolchains/.gitignore
new file mode 100644
index 0000000..13489ce
--- /dev/null
+++ b/third_party/google-glog/toolchains/.gitignore
@@ -0,0 +1,2 @@
+# allow toolchain files to be tracked by git
+!*.cmake
diff --git a/third_party/google-glog/toolchains/clang-cxx17.cmake b/third_party/google-glog/toolchains/clang-cxx17.cmake
new file mode 100644
index 0000000..09d077a
--- /dev/null
+++ b/third_party/google-glog/toolchains/clang-cxx17.cmake
@@ -0,0 +1,13 @@
+# Sample toolchain file for building with gcc compiler
+#
+# Typical usage:
+#    *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake"
+
+# set compiler
+set(CMAKE_C_COMPILER clang)
+set(CMAKE_CXX_COMPILER clang++)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/third_party/google-glog/toolchains/gcc-cxx11.cmake b/third_party/google-glog/toolchains/gcc-cxx11.cmake
new file mode 100644
index 0000000..da1ab57
--- /dev/null
+++ b/third_party/google-glog/toolchains/gcc-cxx11.cmake
@@ -0,0 +1,13 @@
+# Sample toolchain file for building with gcc compiler
+#
+# Typical usage:
+#    *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake"
+
+# set compiler
+set(CMAKE_C_COMPILER gcc)
+set(CMAKE_CXX_COMPILER g++)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/third_party/google-glog/toolchains/gcc-cxx17.cmake b/third_party/google-glog/toolchains/gcc-cxx17.cmake
new file mode 100644
index 0000000..1b834f1
--- /dev/null
+++ b/third_party/google-glog/toolchains/gcc-cxx17.cmake
@@ -0,0 +1,13 @@
+# Sample toolchain file for building with gcc compiler
+#
+# Typical usage:
+#    *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake"
+
+# set compiler
+set(CMAKE_C_COMPILER gcc)
+set(CMAKE_CXX_COMPILER g++)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/third_party/google-glog/toolchains/gcc-cxx98.cmake b/third_party/google-glog/toolchains/gcc-cxx98.cmake
new file mode 100644
index 0000000..5697ab2
--- /dev/null
+++ b/third_party/google-glog/toolchains/gcc-cxx98.cmake
@@ -0,0 +1,13 @@
+# Sample toolchain file for building with gcc compiler
+#
+# Typical usage:
+#    *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake"
+
+# set compiler
+set(CMAKE_C_COMPILER gcc)
+set(CMAKE_CXX_COMPILER g++)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 98)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/third_party/google-glog/toolchains/gcc-gnuxx11.cmake b/third_party/google-glog/toolchains/gcc-gnuxx11.cmake
new file mode 100644
index 0000000..91f0e4a
--- /dev/null
+++ b/third_party/google-glog/toolchains/gcc-gnuxx11.cmake
@@ -0,0 +1,13 @@
+# Sample toolchain file for building with gcc compiler
+#
+# Typical usage:
+#    *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/gcc.cmake"
+
+# set compiler
+set(CMAKE_C_COMPILER gcc)
+set(CMAKE_CXX_COMPILER g++)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS ON)
diff --git a/third_party/google-glog/toolchains/linux-mingw-w64-cxx11.cmake b/third_party/google-glog/toolchains/linux-mingw-w64-cxx11.cmake
new file mode 100644
index 0000000..9c6e126
--- /dev/null
+++ b/third_party/google-glog/toolchains/linux-mingw-w64-cxx11.cmake
@@ -0,0 +1,33 @@
+# Sample toolchain file for building for Windows from an Ubuntu Linux system.
+#
+# Typical usage:
+#    *) install cross compiler: `sudo apt-get install mingw-w64`
+#    *) cmake -H. -B_build_mingw -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/linux-mingw-w64.cmake"
+
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_SYSTEM_PROCESSOR x86_64)
+set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
+
+# set compiler
+set(CMAKE_C_COMPILER   ${TOOLCHAIN_PREFIX}-gcc)
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
+set(CMAKE_RC_COMPILER  ${TOOLCHAIN_PREFIX}-windres)
+
+# target environment on the build host system
+#   set 1st to dir with the cross compiler's C/C++ headers/libs
+set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
+
+# modify default behavior of FIND_XXX() commands to
+# search for headers/libs in the target environment and
+# search for programs in the build host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+# use emulator for `try_run` calls
+set(CMAKE_CROSSCOMPILING_EMULATOR wine64)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/third_party/google-glog/toolchains/linux-mingw-w64-cxx17.cmake b/third_party/google-glog/toolchains/linux-mingw-w64-cxx17.cmake
new file mode 100644
index 0000000..1c363f1
--- /dev/null
+++ b/third_party/google-glog/toolchains/linux-mingw-w64-cxx17.cmake
@@ -0,0 +1,33 @@
+# Sample toolchain file for building for Windows from an Ubuntu Linux system.
+#
+# Typical usage:
+#    *) install cross compiler: `sudo apt-get install mingw-w64`
+#    *) cmake -H. -B_build_mingw -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/linux-mingw-w64.cmake"
+
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_SYSTEM_PROCESSOR x86_64)
+set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
+
+# set compiler
+set(CMAKE_C_COMPILER   ${TOOLCHAIN_PREFIX}-gcc)
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
+set(CMAKE_RC_COMPILER  ${TOOLCHAIN_PREFIX}-windres)
+
+# target environment on the build host system
+#   set 1st to dir with the cross compiler's C/C++ headers/libs
+set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
+
+# modify default behavior of FIND_XXX() commands to
+# search for headers/libs in the target environment and
+# search for programs in the build host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+# use emulator for `try_run` calls
+set(CMAKE_CROSSCOMPILING_EMULATOR wine64)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/third_party/google-glog/toolchains/linux-mingw-w64-gnuxx11.cmake b/third_party/google-glog/toolchains/linux-mingw-w64-gnuxx11.cmake
new file mode 100644
index 0000000..9902964
--- /dev/null
+++ b/third_party/google-glog/toolchains/linux-mingw-w64-gnuxx11.cmake
@@ -0,0 +1,33 @@
+# Sample toolchain file for building for Windows from an Ubuntu Linux system.
+#
+# Typical usage:
+#    *) install cross compiler: `sudo apt-get install mingw-w64`
+#    *) cmake -H. -B_build_mingw -DCMAKE_TOOLCHAIN_FILE="${PWD}/toolchains/linux-mingw-w64.cmake"
+
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_SYSTEM_PROCESSOR x86_64)
+set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)
+
+# set compiler
+set(CMAKE_C_COMPILER   ${TOOLCHAIN_PREFIX}-gcc)
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
+set(CMAKE_RC_COMPILER  ${TOOLCHAIN_PREFIX}-windres)
+
+# target environment on the build host system
+#   set 1st to dir with the cross compiler's C/C++ headers/libs
+set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
+
+# modify default behavior of FIND_XXX() commands to
+# search for headers/libs in the target environment and
+# search for programs in the build host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+# use emulator for `try_run` calls
+set(CMAKE_CROSSCOMPILING_EMULATOR wine64)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS ON)
diff --git a/third_party/google-glog/toolchains/mingw-cxx11.cmake b/third_party/google-glog/toolchains/mingw-cxx11.cmake
new file mode 100644
index 0000000..873f623
--- /dev/null
+++ b/third_party/google-glog/toolchains/mingw-cxx11.cmake
@@ -0,0 +1,13 @@
+# Sample toolchain file for building with gcc compiler
+#
+# Typical usage:
+#    *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="%cd%\toolchains\mingw.cmake"
+
+# set compiler
+set(CMAKE_C_COMPILER gcc)
+set(CMAKE_CXX_COMPILER g++)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/third_party/google-glog/toolchains/mingw-cxx17.cmake b/third_party/google-glog/toolchains/mingw-cxx17.cmake
new file mode 100644
index 0000000..c0c89cc
--- /dev/null
+++ b/third_party/google-glog/toolchains/mingw-cxx17.cmake
@@ -0,0 +1,13 @@
+# Sample toolchain file for building with gcc compiler
+#
+# Typical usage:
+#    *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="%cd%\toolchains\mingw.cmake"
+
+# set compiler
+set(CMAKE_C_COMPILER gcc)
+set(CMAKE_CXX_COMPILER g++)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
diff --git a/third_party/google-glog/toolchains/mingw-gnuxx11.cmake b/third_party/google-glog/toolchains/mingw-gnuxx11.cmake
new file mode 100644
index 0000000..6633705
--- /dev/null
+++ b/third_party/google-glog/toolchains/mingw-gnuxx11.cmake
@@ -0,0 +1,13 @@
+# Sample toolchain file for building with gcc compiler
+#
+# Typical usage:
+#    *) cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE="%cd%\toolchains\mingw.cmake"
+
+# set compiler
+set(CMAKE_C_COMPILER gcc)
+set(CMAKE_CXX_COMPILER g++)
+
+# set c++ standard
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS YES)
diff --git a/third_party/google-glog/toolchains/vs-14-2015-sdk-8-1.cmake b/third_party/google-glog/toolchains/vs-14-2015-sdk-8-1.cmake
new file mode 100644
index 0000000..463bee0
--- /dev/null
+++ b/third_party/google-glog/toolchains/vs-14-2015-sdk-8-1.cmake
@@ -0,0 +1,2 @@
+# set c++ standard
+set(CMAKE_SYSTEM_VERSION 8.1)
diff --git a/third_party/google-glog/toolchains/vs-14-2015-win64.cmake b/third_party/google-glog/toolchains/vs-14-2015-win64.cmake
new file mode 100644
index 0000000..00beda2
--- /dev/null
+++ b/third_party/google-glog/toolchains/vs-14-2015-win64.cmake
@@ -0,0 +1 @@
+# dummy, nothing extra to set
diff --git a/third_party/google-glog/toolchains/vs-15-2017-win64-cxx17.cmake b/third_party/google-glog/toolchains/vs-15-2017-win64-cxx17.cmake
new file mode 100644
index 0000000..5e4e936
--- /dev/null
+++ b/third_party/google-glog/toolchains/vs-15-2017-win64-cxx17.cmake
@@ -0,0 +1,2 @@
+# set c++ standard
+set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} /std:c++17")
diff --git a/third_party/google-glog/toolchains/vs-15-2017-win64.cmake b/third_party/google-glog/toolchains/vs-15-2017-win64.cmake
new file mode 100644
index 0000000..00beda2
--- /dev/null
+++ b/third_party/google-glog/toolchains/vs-15-2017-win64.cmake
@@ -0,0 +1 @@
+# dummy, nothing extra to set
diff --git a/tools/ci/run-tests.sh b/tools/ci/run-tests.sh
index bcb4c2a..51bf12e 100755
--- a/tools/ci/run-tests.sh
+++ b/tools/ci/run-tests.sh
@@ -2,7 +2,9 @@
 set -e
 set -x
 
-bazel test -c opt --curses=no --color=no //...
-bazel build -c opt --curses=no --color=no //... --cpu=roborio
+TARGETS='//... @com_github_google_glog//...'
+
+bazel test -c opt --curses=no --color=no ${TARGETS}
+bazel build -c opt --curses=no --color=no ${TARGETS} --cpu=roborio
+bazel build --curses=no --color=no ${TARGETS} --cpu=armhf-debian
 bazel build -c opt --curses=no --color=no //motors/... --cpu=cortex-m4f
-bazel build --curses=no --color=no //... --cpu=armhf-debian